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

算法,c#,实现,自定义,字符串,编码,围栏,解码,方法 · 浏览次数 : 96

小编点评

```C# using System; using System.Collections.Generic; public class RailFenceCipher { // ...排版方法... public static string Encode(string s, int n) { // ...排版方法... } public static string Decode(string s, int n) { // ...排版方法... } } ``` **注释:** * `RailFenceCipher` 类包含 `Encode` 和 `Decode` 方法,用于加密和解密字符串。 * ``RandomTests`` 方法用于测试字符串的排列顺序。 * `Shuffle` 方法用于随机排列字符串的元素。 * ``for``循环用于排版方法的调用。

正文

编写一个函数/方法,它接受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#实现自定义字符串编码及围栏解码方法相似的内容:

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

编写一个函数/方法,它接受2个参数、一个字符串和轨道数,并返回ENCODED字符串。 编写第二个函数/方法,它接受2个参数、一个编码字符串和轨道数,并返回DECODED字符串。 然后使用围栏密码对其进行解码。 这种密码用于通过将每个字符沿着一组“竖状轨道”依次放在对角线上来对字符串进行编码。首先开始

【算法】用c#实现德州扑克卡牌游戏规则

德州扑克是一种牌类游戏,可多人参与,它的玩法是,玩家每人发两张底牌,桌面依次发5张公共牌,玩家用自己的两张底牌和5张公共牌自由组合,按大小决定胜负。 使用c#完成功能Hand()以返回手牌类型和按重要性递减顺序排列的等级列表,用于与同类型的其他手牌进行比较,即最佳手牌。 可能的手牌按价值降序排列:

图解B树及C#实现(2)数据的读取及遍历

前言 本文为系列文章 B树的定义及数据的插入 数据的读取及遍历(本文) 数据的删除 前一篇文章为大家介绍了 B树 的基本概念及其插入算法。本文将基于前一篇的内容,为大家介绍插入到 B树 中的数据该怎么读取及遍历, 本文的代码基于前一篇文章的代码,已经实现的功能可能会被省略,只介绍新增的功能。 在本文

【算法】用c#实现计算方法中的经典降幂优化策略,减少计算复杂度

对于给定的数组[x1,x2,x3,…,xn],计算幂的累积:x1^(x2^(x3^(…^xn))的最后一位(十进制)数字。 例如,对于数组[3,4,2],您的代码应该返回1,因为3^(4^2)=3^16=43046721。 结果的增长得快得令人难以置信。例如,9^(9^9)有超过3.69亿个数字。你

【算法】湖心岛上的数学梦--用c#实现一元多次方程的展开式

每天清晨,当第一缕阳光洒在湖面上,一个身影便会出现在湖心小岛上。她坐在一块大石头上,周围被茂盛的植物环绕,安静地沉浸在数学的世界中。 这个姑娘叫小悦,她的故事在这个美丽的湖心小岛上展开。每天早晨,她都会提前来到湖边,仔细观察水下的植物,然后抽出时间来钻研一元x次方程。她身上的气息混合着湖水的清新和植

.NET周报 【4月第2期 2023-04-08】

国内文章 LRU缓存替换策略及C#实现 https://www.cnblogs.com/eventhorizon/p/17290125.html 这篇文章讲述了缓存替换策略,特别是LRU算法。LRU算法基于这样一个假设:如果数据最近被访问过,那么将来被访问的几率也更高。通常我们会用双向链表来实现这个

数据结构与算法大作业:走迷宫程序(实验报告)

好家伙,本篇为应付老师的实验报告,有需要的拿去抄吧 思路讲解在上一篇: 数据结构与算法大作业:走迷宫程序(C,代码以及思路) 一、作业目的 1、 掌握用数据结构的知识进行程序设计。 2、 应用所学的数据结构完成一个具有一定实际意义的应用程序的设计、编码、调试,锻炼实践动手能力,提高编程水平。 二、作

一个开源且全面的C#算法实战教程

前言 算法在计算机科学和程序设计中扮演着至关重要的角色,如在解决问题、优化效率、决策优化、实现计算机程序、提高可靠性以及促进科学融合等方面具有广泛而深远的影响。今天大姚给大家分享一个开源、免费、全面的C#算法实战教程:TheAlgorithms/C-Sharp。 C#经典十大排序算法(完结) 支持C

7.1 C++ STL 非变易查找算法

C++ STL 中的非变易算法(Non-modifying Algorithms)是指那些不会修改容器内容的算法,是C++提供的一组模板函数,该系列函数不会修改原序列中的数据,而是对数据进行处理、查找、计算等操作,并通过迭代器实现了对序列元素的遍历与访问。由于迭代器与算法是解耦的,因此非变易算法可以广泛地应用于各种容器上,提供了极高的通用性和灵活性。

C#中使用CAS实现无锁算法

CAS 的基本概念 CAS(Compare-and-Swap)是一种多线程并发编程中常用的原子操作,用于实现多线程间的同步和互斥访问。 它操作通常包含三个参数:一个内存地址(通常是一个共享变量的地址)、期望的旧值和新值。 CompareAndSwap(内存地址,期望的旧值,新值) CAS 操作会比较