好汣不见 发表于 2023-8-21 09:51:14

【算法】用c#实现自定义字符串编码及围栏解码方法

编写一个函数/方法,它接受2个参数、一个字符串和轨道数,并返回ENCODED字符串。
编写第二个函数/方法,它接受2个参数、一个编码字符串和轨道数,并返回DECODED字符串。
然后使用围栏密码对其进行解码。
这种密码用于通过将每个字符沿着一组“竖状轨道”依次放在对角线上来对字符串进行编码。首先开始对角向下移动。当你到达底部时,反转方向,对角向上移动,直到你到达顶部轨道。继续,直到到达字符串的末尾。然后从左到右读取每个“尾号”以导出编码字符串。
例如,字符串“WEAREDISCOVEREDFLEATONCE”可以在三轨系统中表示如下:
W E C R L T E
E R D S O E E F E A O C
A I V D E N
编码的字符串将是:
WECRLTEERDSOEEFEAOCAIVDEN
对于编码和解码,假设尾号的数量>=2,并且传递空字符串将返回空字符串。
请注意,为了简单起见,上面的示例排除了标点符号和空格。然而,也有一些测试包括标点符号。不要过滤掉标点符号,因为它们是字符串的一部分。
算法实现:
1 using System;
2 using System.Linq;
3
4 public class RailFenceCipher
5 {
6    public static string Encode(string s, int n)
7    {
8      var mod = (n - 1) * 2;
9      return string.Concat(s.Select((c, i) => new { c, i })
10         .OrderBy(a => Math.Min(a.i % mod, mod - a.i % mod))
11         .Select(a => a.c));
12    }
13
14    public static string Decode(string s, int n)
15    {
16      var mod = (n - 1) * 2;
17      var pattern = Enumerable.Range(0, s.Length)
18         .OrderBy(i => Math.Min(i % mod, mod - i % mod));
19      return string.Concat(s.Zip(pattern, (c, i) => new { c, i })
20         .OrderBy(a => a.i).Select(a => a.c));
21    }
22 }测试用例:
1 using NUnit.Framework;
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 public class SolutionTest
6 {
7   
8   public void BasicTests()
9   {
10         string[][] config =
11         {
12             new[] { "Hello, World!", "Hoo!el,Wrdl l" },               // encode
13             new[] { "Hello, World!", "Hlo ol!el,Wrd" },               // encode
14             new[] { "Hello, World!", "H !e,Wdloollr" },               // encode
15             new[] { "H !e,Wdloollr", "Hello, World!" },               //decode
16             new[] { "", "" },                            // encode
17             new[] { "", "" },                            //decode
18             new[] { "WEAREDISCOVEREDFLEEATONCE", "WECRLTEERDSOEEFEAOCAIVDEN" },   // encode
19             new[] { "WECRLTEERDSOEEFEAOCAIVDEN", "WEAREDISCOVEREDFLEEATONCE" },   //decode
20             new[] { "WEAREDISCOVEREDFLEEATONCE", "WIREEEDSEEEACAECVDLTNROFO" },   // encode
21             new[] { "WIREEEDSEEEACAECVDLTNROFO", "WEAREDISCOVEREDFLEEATONCE" },   //decode
22             new[] { "WEAREDISCOVEREDFLEEATONCE", "WCLEESOFECAIVDENRDEEAOERT" },   // encode
23             new[] { "WECRLTEERDSOEEFEAOCAIVDEN", "WLSADOOTEEECEAEECRFINVEDR" }    //decode
24         };
25         int[] rails = { 3, 2, 4, 4, 3, 3, 3, 3, 4, 4, 5, 5 };
26         for (int i = 0; i < config.Length; i++)
27         {
28             var actual = i % 2 == 0 || i == 1
29               ? RailFenceCipher.Encode(config, rails)
30               : RailFenceCipher.Decode(config, rails);
31
32             Assert.AreEqual(config, actual);
33         }
34   }
35
36   /* *****************
37      *   RANDOM TESTS
38      * *****************/
39
40   private class Sol
41   {
42         private static IEnumerable<T> Fencer<T>(int n, IEnumerable<T> str)
43         {
44             var rails = Enumerable.Range(0, n).Select(r => new List<T>()).ToList();
45             int[] data = { 0, 1 };
46             int x = 0, dx = 1;
47             foreach (var t in str)
48             {
49               rails].Add(t);
50               if (data == n - 1 && data > 0 || data == 0 && data < 0)
51                     data *= -1;
52               data += data;
53             }
54             return rails.SelectMany(lst => lst);
55         }
56
57         public static string Encode(string s, int n) => new string(Fencer(n, s).ToArray());
58
59         public static string Decode(string s, int n)
60         {
61             char[] arr = new char;
62             int[] j = { 0 };
63             Fencer(n, Enumerable.Range(0, s.Length)).ToList().ForEach(i => arr = s++]);
64             return new string(arr);
65         }
66   }
67
68   private Random rnd = new Random();
69
70   private int Rand(int start, int end) { return start + rnd.Next(end - start); }
71
72   
73   public void FixedStringVariousRails()
74   {
75         var msg = "WEAREDISCOVEREDFLEEATONCE";
76         Console.WriteLine($"Input for these tests:\n{msg}");
77
78         for (int r = 0; r < 10; r++)
79         {
80             var rails = Rand(2, 11);
81             var exp = Sol.Encode(msg, rails);
82             Assert.AreEqual(exp, RailFenceCipher.Encode(msg, rails));
83
84             rails = Rand(2, 11);
85             exp = Sol.Decode(msg, rails);
86             Assert.AreEqual(exp, RailFenceCipher.Decode(msg, rails));
87         }
88   }
89
90   private static string lorem = "Amet non facere minima iure unde, provident, "
91                                 + "veritatis officiis asperiores ipsa eveniet sit! Deserunt "
92                                 + "autem excepturi quibusdam iure unde! Porro alias distinctio "
93                                 + "ipsam iure exercitationem molestiae. Voluptate fugiat quasi maiores!jk";
94   private static List<string> lorarr = lorem.Split(' ').ToList();
95
96   
97   public void RandomTests()
98   {
99         Console.WriteLine($"Base string for these tests (or a shuffled version):\n{lorem}");
100
101         for (int r = 0; r < 50; r++)
102         {
103             var msg = Shuffle();
104             int rails = Rand(2, 51);
105             var exp = Sol.Encode(msg, rails);
106             Assert.AreEqual(exp, RailFenceCipher.Encode(msg, rails));
107
108             msg = Shuffle();
109             rails = Rand(2, 51);
110             exp = Sol.Decode(msg, rails);
111             Assert.AreEqual(exp, RailFenceCipher.Decode(msg, rails));
112         }
113   }
114
115   private string Shuffle()
116   {
117         Shuffle(lorarr);
118         return string.Join(" ", lorarr);
119   }
120
121   public static void Shuffle<T>(List<T> deck)
122   {
123         var rnd = new Random();
124         for (int n = deck.Count - 1; n > 0; --n)
125         {
126             int k = rnd.Next(n + 1);
127             T temp = deck;
128             deck = deck;
129             deck = temp;
130         }
131   }
132 } 

来源:https://www.cnblogs.com/lan80/archive/2023/08/21/17645151.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 【算法】用c#实现自定义字符串编码及围栏解码方法