出于好奇而编写递归字符串反向函数,但在那里遇到了一些XOR问题。这个函数的重点是不使用迭代器,这就是它是递归函数的原因。这不是功课,只是好奇心。
private static char[] ReverseNL(char[] arr, int index)
{
var len = arr.Length;
if (index > 0)
arr[len - index] ^= arr[index - 1];
return index-- < 1 ? arr : ReverseNL(arr, index);
}
它似乎堵塞了我的字符串的第一部分
“嘿那里堆叠!”成为“我♫→A←E↨rehtyeh”
这句话的前半部分总是混乱......
更新..
我认为这里并不需要XOR ..所以使用了基本的作业,也摆脱了回归。
private static void ReverseNL(char[] arr, int index) {
var len = arr.Length;
if (index > 0 && index > len / 2) {
var c = arr[len - index];
arr[len - index] = arr[index - 1];
arr[index - 1] = c;
index--;
ReverseNL(arr, index);
}
}
答案 0 :(得分:7)
递归几乎总是用于使问题更简单。递归算法通常也具有功能性(尽管它们不一定是这样)。
在反转字符串(或char[]
)的情况下,“更简单”意味着“在较小的数组上操作”。
例如,您可以按如下方式减少:
"test"
"est" 't'
"st" 'e'
"t" 's'
"" 't'
(左侧是数据减少;右侧是剪切数据)。
在伪代码中,您可以按如下方式执行缩减:
char[] reverse(char[] data) {
if (data.Count() == 0) {
return new char[] { };
}
char cut = data.First();
char[] rest = data.Skip(1);
char [] restReversed = reverse(rest);
// ???
}
我会让你知道接下来需要用你的数据做些什么。
答案 1 :(得分:6)
可能不是最有效的,但这应该会给你一些关于如何让递归工作的想法...
static string ReverseNL (string s)
{
if ((s == null) || (s.Length <= 1))
{
return s;
}
return ReverseNL(s.Substring(1)) + s[0];
}
static void Main(string[] args)
{
string src = "The quick brown fox";
Console.WriteLine(src);
src = ReverseNL(src);
Console.WriteLine(src);
}
答案 2 :(得分:4)
如果你想要一个使用XOR和递归的解决方案,试试这个:
private static void ReverseNL(char[] arr, int index)
{
if (index <arr.Length/2)
{
arr[index] ^= arr[arr.Length - index-1];
arr[arr.Length - index-1] ^= arr[index ];
arr[index] ^= arr[arr.Length - index-1];
ReverseNL(arr,++index);
}
}
您不需要返回任何内容,因为所有内容都在数组中完成。当然你可以删除XOR部分并只交换元素,但这是更酷。 ;)
(编辑:索引应从0开始)
答案 3 :(得分:1)
一个观察结果:您正在操作并返回一个数组。始终是相同的阵列。数组始终是引用。
这意味着您的退货声明过于复杂且具有误导性。在所有情况下都以return arr;
结束。
考虑一般提示的一部分:使其更简单,您将更容易看到错误。 1}}仅在返回语句中应该引起一个红旗。
--
答案 4 :(得分:0)
在这个特定的例子中,我宁愿这样做:
return arr.Reverse();
答案 5 :(得分:0)
必须调用XOR两次才能交换一对元素。它只在阵列的前半部分被调用一次。 (在编辑中:严格来说,每次分配只调用一次,因此净效果就像在数组的一半上进行双XOR交换一样。)