编写一个函数/方法,它接受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 [Test]
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[i][0], rails[i])
30 : RailFenceCipher.Decode(config[i][0], rails[i]);
31
32 Assert.AreEqual(config[i][1], 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[data[x]].Add(t);
50 if (data[x] == n - 1 && data[dx] > 0 || data[x] == 0 && data[dx] < 0)
51 data[dx] *= -1;
52 data[x] += data[dx];
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[s.Length];
62 int[] j = { 0 };
63 Fencer(n, Enumerable.Range(0, s.Length)).ToList().ForEach(i => arr[i] = s[j[0]++]);
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 [Test]
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 [Test]
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[n];
128 deck[n] = deck[k];
129 deck[k] = temp;
130 }
131 }
132 }

【算法】用c#实现自定义字符串编码及围栏解码方法的更多相关文章

  1. 完整的java字符串编码转换代码

    package book.String; import java.io.UnsupportedEncodingException; /** *//** * 转换字符串的编码 * @author joe ...

  2. JAVA字符串编码转换常用类

    无论是对程序的本地化还是国际化,都会涉及到字符编码的转换的问题.尤其在web应用中常常需要处理中文字符,这时就需要进行字符串的编码转换,将字符串编码转换为GBK或者GB2312.一.关键技术点:    ...

  3. java字符串应用之字符串编码转换

    [转载]原文地址:https://blog.csdn.net/zhouyong80/article/details/1900100 无论是对程序的本地化还是国际化,都会涉及到字符编码的转换的问题.尤其 ...

  4. JAVA 字符串编码转换

    /** * 字符串编码转换的实现方法 * @param str 待转换编码的字符串 * @param newCharset 目标编码 * @return * @throws UnsupportedEn ...

  5. 【算法题12 解码方法decode way】

    1.来源LeetCode91 一条包含字母 A-Z 的消息通过以下方式进行了编码: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 给定一个只包含数字的非空字符串,请 ...

  6. Mapreduce中的字符串编码

    Mapreduce中的字符串编码 $$$ Shuffle的执行过程,需要经过多次比较排序.如果对每一个数据的比较都需要先反序列化,对性能影响极大. RawComparator的作用就不言而喻,能够直接 ...

  7. 第一百零八节,JavaScript,内置对象,Global对象字符串编码解码,Math对象数学公式

    JavaScript,内置对象,Global对象字符串编码解码,Math对象数学公式 学习要点: 1.Global对象 2.Math对象 ECMA-262对内置对象的定义是:"由ECMASc ...

  8. 【字符串算法1】 再谈字符串Hash(优雅的暴力)

    [字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述  [字符串算法1] 字符串Hash 老版原文: RK哈希(Rabin_Ka ...

  9. c# 自定义Base16编码解码

               一.自定义Base16编码原理                  Base16编码跟Base64编码原理上有点不同,当然前面转换是一样的,都是是将输入的字符串根据默认编码转换成一 ...

  10. 使用自己的Python函数处理Protobuf中的字符串编码

    我目前所在的项目是一个老项目,里面的字符串编码有点乱,数据库中有些是GB2312,有些是UTF8:代码中有些是GBK,有些是UTF8,代码中转来转去,经常是不太清楚当前这个字符串是什么编码,由于是老项 ...

随机推荐

  1. 基于FPGA的数字钟设计---第三版

    欢迎各位朋友关注"郝旭帅电子设计团队",本篇为各位朋友介绍基于FPGA的数字钟设计---第三版. 功能说明: 1. 在数码管上面显示时分秒(共计六个数码管,前两个显示小时:中间两个 ...

  2. 推荐一款模拟浏览器自动化操作神器!Mechanize

    大家好,我是狂师! 今天给大家推荐一款用于模拟浏览器行为以进行网页自动化操作Python库:Mechanize. 1.介绍 Mechanize是Python中的一个库,它被设计用来自动化网页浏览和数据 ...

  3. SCSS随笔-mixin与@extend

    变量 定义变量 $color-white: white; 使用变量 body { background-color: $color-white; } @mixin 与 @include 定义mixin ...

  4. 一文带你了解.NET能做什么?

    前言 在DotNetGuide技术社区微信交流群经常看到有小伙伴问:.NET除了能写桌面应用和Web应用还能做什么?今天大姚将通过本篇文章来简单讲讲.NET能做哪些开发,对.NET感兴趣的小伙伴也可以 ...

  5. aardio桌面软件开发 简单,打包后文件小,支持 .net python 和 众多插件

    aardio 编程语言 - 官网 aardio  专注于桌面软件开发,17年一直保持非常活跃地更新( 更新日志 ),aardio 被多年用于生产项目实践,久经测试和锤炼.aardio 在诞生之初就设计 ...

  6. .net Core中实现SHA加密

    #region 用SHA1加密字符串 /// <summary> /// 用SHA1加密字符串 /// </summary> /// <param name=" ...

  7. C++笔记(13)数组的引用和引用的数组

    数组的引用 数组有二个特性,影响作用在数组上的函数:一是不能复制数组,二是使用数组名时, 数组名会自动指向其第一个元素的指针. 因为不能复制,所以无法编写使用数组类型的形参,数组会自动转化为指针.比如 ...

  8. 记一次 .NET某质量检测中心系统 崩溃分析

    一:背景 1. 讲故事 这些天有点意思,遇到的几个程序故障都是和Windows操作系统或者第三方组件有关系,真的有点无语,今天就带给大家一例 IIS 相关的与大家分享,这是一家国企的.NET程序,出现 ...

  9. UML建模工具Astah Pro 8破解教程2022最新最详细版

    (2022最新最详细版)UML建模工具Astah Pro 8破解教程 本文作者严正声明:拒绝盗版行为,打击盗版,痛恨吃白食的家伙,我一直都是坚定思想,有钱了一定要支持正版,所以此文档贡献,只为学习交流 ...

  10. elementUI slider组件,带范围选择实现双向绑定

    网上查过很多相关文章都没有一章是写element ui滑块带范围实现双向绑定 二个滑块二头的数据怎么得到 我的需求是做个时间轴要滑动选择不同的时间 开始很难做最后一点一点摸索得出的结论 好在写出来了先 ...