一道简单有趣的算法题

时间:2021-12-24 10:28:01
在微博上看到的
要求:写一个函数将单词随机打乱
规则:单词首尾字母不变,中间的字母随机打乱

例如:The cost of the citys response to the disaster has spiralled
打乱成: The csot of the ctyis rspoense to the diatsesr has salpirlead

string shuffle(string input)
{
     //给出实现
}

21 个解决方案

#1


代码越精简越好,暂不考虑效率问题

#2


先写一个打乱的方法
然后把字符串按空格分割成数组
然后取每个数组元素去掉首尾的子字符串
然后用写的方法打乱顺序
然后放回去
然后把数组join起来

#3


string init_str = "The cost of the citys response to the disaster has spiralled";

                string result=string.Join(" ",Regex.Split(init_str, @"\s+").Select(a => { 
                    var temp_list=a.ToList();
                    char begin_char = temp_list.First();
                    char end_char = temp_list.Last();
                    temp_list.Remove(begin_char);
                    temp_list.Remove(end_char);
                    temp_list=temp_list.OrderBy(b => Guid.NewGuid()).ToList();//随机
                    return begin_char.ToString()+string.Join("",temp_list)+end_char.ToString();
                    
                }));

#4



string shuffle(string input)
{
  string[] words = input.split(" ");
  Random r = new Random();
  foreach(string word in words)
  {
    for(int i=1; i<word.Length-2; i++)
    {
      int idx = r.Next(0, word.Length-2);
      char c = word[i];
      word[i] = word[idx];
      word[idx] = c;
    }
  }
  return string.Join(words);

#5


string shuffle(string input)
{
Random r=new Random();
return string.Join(" ", input.Split(' ').Select( x => x.First() + string.Join("", x.Skip(1).Take(x.Count() - 2).OrderBy(y => r.Next(-1, 1))) + x.Last()));

#6





引用 3 楼 Return_false 的回复:
string init_str = "The cost of the citys response to the disaster has spiralled";
 
                string result=string.Join(" ",Regex.Split(init_str, @"\s+").Select(a => { 
                    var temp_list=a.ToList();
                    char begin_char = temp_list.First();
                    char end_char = temp_list.Last();
                    temp_list.Remove(begin_char);
                    temp_list.Remove(end_char);
                    temp_list=temp_list.OrderBy( b => Guid.NewGuid()).ToList();//随机
                    return begin_char.ToString()+string.Join("",temp_list)+end_char.ToString();
                     
                }));

学习了

#7


给出我自己的实现,一行代码

Regex.Replace("hello world", @"(?<=\w)\w*(?=\w)", it => it.Value.Length < 2 ? it.Value :                new string(it.Value.OrderBy(_ => rand.Next()).ToArray()));

#8


1.得到你单词的长度。
2.保留你的头和尾
3.string.ToCharArray() 中间的字符串进行 Random 下。从新组合就可以了
4.最后在 join 下 和头尾一组合就完事了。

#9



private static string Shuffle(string s)
{
    if (string.IsNullOrWhiteSpace(s) || s.Length <= 3)
    {
        return s;
    }
    var b = s.Length - 1;
    var a = new List<int>();
    var r = new Random();
    while (a.Count < s.Length - 2)
    {
        var v = r.Next(1, b);
        if (!a.Contains(v))
        {
            a.Add(v);
        }
    }
    var ns = s[0].ToString();
    foreach (var i in a)
    {
        ns += s[i];
    }
    ns += s[s.Length - 1];
    return ns;
}

#10



void Main()
{
string str="The cost of the citys response to the disaster has spiralled";
 
str=string.Join(" ",(from s in str.Split(' ')
    let m=s.ToCharArray() 
let n=m.Count()>3?m.Skip(1).Take(m.Count()-2).OrderBy(x=>Guid.NewGuid()).ToArray():null
select n==null?s:string.Concat(m.First(),new string(n),m.Last())).ToArray());
}

#11


引用 10 楼 q107770540 的回复:
C# code1234567891011void Main(){    string str="The cost of the citys response to the disaster has spiralled";          str=string.Join(" ",(from s in str.Split(' ')        let m=s.ToChar……

我也想这么写来着,没想到用 GUID 排序。~~

#12


string source = "The cost of the citys response to the disaster has spiralled";         
var result=  string.Join(" ",source.Split(' ').Select(p =>p.Length>3?string.Concat(p.First(),new string( p.Skip(1).Take(p.Length-2).OrderBy(c=>Guid.NewGuid()).ToArray()), p.Last()):p));

#13


引用 10 楼 q107770540 的回复:
C# code1234567891011void Main(){    string str="The cost of the citys response to the disaster has spiralled";          str=string.Join(" ",(from s in str.Split(' ')        let m=s.ToChar……


但是这个排序的结果不理想!如果执行多次,基本上这几次的字符串很多位置上的字符都是相同的。:(

#14


保留单词头部和尾部字母,使用库函数next_permutation(p,p+n)就可以了

#15


这个帖子应该标记一下 一道简单有趣的算法题

#16


看过才知道牛人无处不在!

#17


原来有这么多函数可以实现功能,学习了。

#18


引用 5 楼 newxdlysk 的回复:
C# code12345string shuffle(string input){Random r=new Random();return string.Join(" ", input.Split(' ').Select( x => x.First() + string.Join("", x.Skip(1).Take(x.Count() - 2).OrderBy(y =>……


其实能不能解释一下,菜鸟没有看懂

#19


引用 5 楼 newxdlysk 的回复:
C# code12345string shuffle(string input){Random r=new Random();return string.Join(" ", input.Split(' ').Select( x => x.First() + string.Join("", x.Skip(1).Take(x.Count() - 2).OrderBy(y =>……


引用 12 楼 wanghui0380 的回复:
C# code12string source = "The cost of the citys response to the disaster has spiralled";         var result=  string.Join(" ",source.Split(' ').Select(p =>p.Length>3?string.Concat(p.First……

这就是传说中的linq技术吗?




引用 7 楼 huwei001982 的回复:
给出我自己的实现,一行代码

Regex.Replace("hello world", @"(?<=\w)\w*(?=\w)", it => it.Value.Length < 2 ? it.Value :                new string(it.Value.OrderBy(_ => rand.Next()).ToArray()));
       ……


这是传说中的正则表达式吗?

#20


方法真多,最重要的是看谁的代码优雅、简练、通用、高效就是最好的代码了!

#21


笨人写的   不过可以一用 结果是楼主想要的
 string _str = "The cost of the citys response to the disaster has spiralled"; 
          //以空格为分界点 把每个单词放到数组中
            string [] str =  _str.Split(' ');
            int num = 0,count = 0;
            int  []s ={0,str.Length-1};
            Random r = new Random();
            for (int i = 0; i < str.Length - 1; i++)
            {
                Console.Write(str[num] + "  ");
                count++;
                if (count >= 1 && count < str.Length - 1)
                {
                my_loop:
                    num = r.Next(str.Length);
                    if (num == 0 || num == str.Length - 1) goto my_loop;
                    else
                    {
                        for (int j = 0; j < s.Length; j++)
                        {
                            if (s[j] == num) goto my_loop;
                        }
                        Array.Resize(ref s, s.Length + 1);
                        s[s.Length - 1] = num;
                    }
                }
                else Console.WriteLine(str[str.Length - 1]);
            }

#1


代码越精简越好,暂不考虑效率问题

#2


先写一个打乱的方法
然后把字符串按空格分割成数组
然后取每个数组元素去掉首尾的子字符串
然后用写的方法打乱顺序
然后放回去
然后把数组join起来

#3


string init_str = "The cost of the citys response to the disaster has spiralled";

                string result=string.Join(" ",Regex.Split(init_str, @"\s+").Select(a => { 
                    var temp_list=a.ToList();
                    char begin_char = temp_list.First();
                    char end_char = temp_list.Last();
                    temp_list.Remove(begin_char);
                    temp_list.Remove(end_char);
                    temp_list=temp_list.OrderBy(b => Guid.NewGuid()).ToList();//随机
                    return begin_char.ToString()+string.Join("",temp_list)+end_char.ToString();
                    
                }));

#4



string shuffle(string input)
{
  string[] words = input.split(" ");
  Random r = new Random();
  foreach(string word in words)
  {
    for(int i=1; i<word.Length-2; i++)
    {
      int idx = r.Next(0, word.Length-2);
      char c = word[i];
      word[i] = word[idx];
      word[idx] = c;
    }
  }
  return string.Join(words);

#5


string shuffle(string input)
{
Random r=new Random();
return string.Join(" ", input.Split(' ').Select( x => x.First() + string.Join("", x.Skip(1).Take(x.Count() - 2).OrderBy(y => r.Next(-1, 1))) + x.Last()));

#6





引用 3 楼 Return_false 的回复:
string init_str = "The cost of the citys response to the disaster has spiralled";
 
                string result=string.Join(" ",Regex.Split(init_str, @"\s+").Select(a => { 
                    var temp_list=a.ToList();
                    char begin_char = temp_list.First();
                    char end_char = temp_list.Last();
                    temp_list.Remove(begin_char);
                    temp_list.Remove(end_char);
                    temp_list=temp_list.OrderBy( b => Guid.NewGuid()).ToList();//随机
                    return begin_char.ToString()+string.Join("",temp_list)+end_char.ToString();
                     
                }));

学习了

#7


给出我自己的实现,一行代码

Regex.Replace("hello world", @"(?<=\w)\w*(?=\w)", it => it.Value.Length < 2 ? it.Value :                new string(it.Value.OrderBy(_ => rand.Next()).ToArray()));

#8


1.得到你单词的长度。
2.保留你的头和尾
3.string.ToCharArray() 中间的字符串进行 Random 下。从新组合就可以了
4.最后在 join 下 和头尾一组合就完事了。

#9



private static string Shuffle(string s)
{
    if (string.IsNullOrWhiteSpace(s) || s.Length <= 3)
    {
        return s;
    }
    var b = s.Length - 1;
    var a = new List<int>();
    var r = new Random();
    while (a.Count < s.Length - 2)
    {
        var v = r.Next(1, b);
        if (!a.Contains(v))
        {
            a.Add(v);
        }
    }
    var ns = s[0].ToString();
    foreach (var i in a)
    {
        ns += s[i];
    }
    ns += s[s.Length - 1];
    return ns;
}

#10



void Main()
{
string str="The cost of the citys response to the disaster has spiralled";
 
str=string.Join(" ",(from s in str.Split(' ')
    let m=s.ToCharArray() 
let n=m.Count()>3?m.Skip(1).Take(m.Count()-2).OrderBy(x=>Guid.NewGuid()).ToArray():null
select n==null?s:string.Concat(m.First(),new string(n),m.Last())).ToArray());
}

#11


引用 10 楼 q107770540 的回复:
C# code1234567891011void Main(){    string str="The cost of the citys response to the disaster has spiralled";          str=string.Join(" ",(from s in str.Split(' ')        let m=s.ToChar……

我也想这么写来着,没想到用 GUID 排序。~~

#12


string source = "The cost of the citys response to the disaster has spiralled";         
var result=  string.Join(" ",source.Split(' ').Select(p =>p.Length>3?string.Concat(p.First(),new string( p.Skip(1).Take(p.Length-2).OrderBy(c=>Guid.NewGuid()).ToArray()), p.Last()):p));

#13


引用 10 楼 q107770540 的回复:
C# code1234567891011void Main(){    string str="The cost of the citys response to the disaster has spiralled";          str=string.Join(" ",(from s in str.Split(' ')        let m=s.ToChar……


但是这个排序的结果不理想!如果执行多次,基本上这几次的字符串很多位置上的字符都是相同的。:(

#14


保留单词头部和尾部字母,使用库函数next_permutation(p,p+n)就可以了

#15


这个帖子应该标记一下 一道简单有趣的算法题

#16


看过才知道牛人无处不在!

#17


原来有这么多函数可以实现功能,学习了。

#18


引用 5 楼 newxdlysk 的回复:
C# code12345string shuffle(string input){Random r=new Random();return string.Join(" ", input.Split(' ').Select( x => x.First() + string.Join("", x.Skip(1).Take(x.Count() - 2).OrderBy(y =>……


其实能不能解释一下,菜鸟没有看懂

#19


引用 5 楼 newxdlysk 的回复:
C# code12345string shuffle(string input){Random r=new Random();return string.Join(" ", input.Split(' ').Select( x => x.First() + string.Join("", x.Skip(1).Take(x.Count() - 2).OrderBy(y =>……


引用 12 楼 wanghui0380 的回复:
C# code12string source = "The cost of the citys response to the disaster has spiralled";         var result=  string.Join(" ",source.Split(' ').Select(p =>p.Length>3?string.Concat(p.First……

这就是传说中的linq技术吗?




引用 7 楼 huwei001982 的回复:
给出我自己的实现,一行代码

Regex.Replace("hello world", @"(?<=\w)\w*(?=\w)", it => it.Value.Length < 2 ? it.Value :                new string(it.Value.OrderBy(_ => rand.Next()).ToArray()));
       ……


这是传说中的正则表达式吗?

#20


方法真多,最重要的是看谁的代码优雅、简练、通用、高效就是最好的代码了!

#21


笨人写的   不过可以一用 结果是楼主想要的
 string _str = "The cost of the citys response to the disaster has spiralled"; 
          //以空格为分界点 把每个单词放到数组中
            string [] str =  _str.Split(' ');
            int num = 0,count = 0;
            int  []s ={0,str.Length-1};
            Random r = new Random();
            for (int i = 0; i < str.Length - 1; i++)
            {
                Console.Write(str[num] + "  ");
                count++;
                if (count >= 1 && count < str.Length - 1)
                {
                my_loop:
                    num = r.Next(str.Length);
                    if (num == 0 || num == str.Length - 1) goto my_loop;
                    else
                    {
                        for (int j = 0; j < s.Length; j++)
                        {
                            if (s[j] == num) goto my_loop;
                        }
                        Array.Resize(ref s, s.Length + 1);
                        s[s.Length - 1] = num;
                    }
                }
                else Console.WriteLine(str[str.Length - 1]);
            }