2012-06-07 33 views
1

我想在一个字符串的随机部分插入随机数量的点(从1到7)而不会破坏布局。插入随机数量的点到最小不同位置的字符串?

这是我当前的代码:

Random rand = new Random(); 
string[] words = iTemplate.Text.Split(' '); 
string result = string.Empty; 
for (int i = 0; i < words.Count(); i++) 
{ 
    string word = words[i]; 
    if (rand.Next(i, words.Count()) == i) 
    { 
     for (int dots = rand.Next(1, 7); dots > 0; dots--) 
      word += "."; 
    } 
    result += word + " "; 
} 

是否有更有效的还是不错的LINQ的选择呢?

现在,由于它的随机性,可能会出现没有点出现的情况。我通过使用if (rand.Next(i, words.Count()) == i)缩小了它的范围,但似乎仍然有效,但仍然有些结果只显示有1到3个插入点的地方。

我怎么能保证在这个过程中点至少插入4个不同的地方?

样本数据/结果作为每评论请求:

string template = "Hi, this is a template with several words on it and I want to place random dots on 4 different random places every time I run the function"; 

结果1:

string result = "Hi, this... is a template with several.. words on it and. I want to place random dots on 4 different random...... places every time I run the function"; 

结果2:

string result = "Hi, this is a template. with several... words on it and I want to..... place random dots on 4 different random. places every time I run the function"; 

结果3:

string result = "Hi, this. is a template with... several words on it and I want to place random.. dots on 4 different random....... places every time I run the.. function"; 
+1

你可以给我们之前/之后的例子你想完成什么,你的要求是相当混乱。 –

+0

@ m-y添加样本数据以及结果每次运行时的样子。 – Guapo

回答

0

这将确保你加点到至少4个字,以及不添加尾随的空间在最终的字符串。

Random rand = new Random(); 
string[] words = iTemplate.Text.Split(' '); 
// Insert dots onto at least 4 words 
int numInserts = rand.Next(4, words.Count()); 
// Used later to store which indexes have already been used 
Dictionary<int, bool> usedIndexes = new Dictionary<int, bool>(); 
for (int i = 0; i < numInserts; i++) 
{ 
    int idx = rand.Next(1, words.Count()); 
    // Don't process the same word twice 
    while (usedIndexes.ContainsKey(idx)) 
    { 
     idx = rand.Next(1, words.Count()); 
    } 
    // Mark this index as used 
    usedIndexes.Add(idx, true); 
    // Append the dots 
    words[idx] = words[idx] + new String('.', rand.Next(1, 7)); 
} 
// String.Join will put the separator between each word, 
// without the trailing " " 
string result = String.Join(" ", words); 
Console.WriteLine(result); 

此代码假定您确实在iTemplate.Text中至少有4个单词。如果有可能你不会,你应该添加一些额外的验证逻辑。

2
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Random rand = new Random(); 
     string[] words = "Now is the time for all good men to come to the aid of their countrymen".Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 
     if (words.Length > 0) 
     { 
      // Generate a list of integers from 0 to words.Length - 1 
      List<int> addIndices = Enumerable.Range(0, words.Length).ToList(); 
      // Shuffle those indices 
      Shuffle(addIndices, rand); 
      // Pick the number of words that will have dots added 
      int addCount = rand.Next(4, Math.Max(4, words.Length)); 
      // Truncate the array so that it only contains the first addCount items 
      addIndices.RemoveRange(addCount, addIndices.Count - addCount); 

      StringBuilder result = new StringBuilder(); 
      for (int i = 0; i < words.Length; i++) 
      { 
       result.Append(words[i]); 
       if (addIndices.Contains(i)) // If the random indices list contains this index, add dots 
        result.Append('.', rand.Next(1, 7)); 
       result.Append(' '); 
      } 

      Console.WriteLine(result.ToString()); 
     } 
    } 

    private static void Shuffle<T>(IList<T> array, Random rand) 
    { 
     // Kneuth-shuffle 
     for (int i = array.Count - 1; i > 0; i--) 
     { 
      // Pick random element to swap. 
      int j = rand.Next(i + 1); // 0 <= j <= i 
      // Swap. 
      T tmp = array[j]; 
      array[j] = array[i]; 
      array[i] = tmp; 
     } 
    } 
} 
+0

+1不错,真的简化了我丑陋的代码,似乎是从bm更快:)第二个问题的任何想法? – Guapo

+0

@Guapo试试那个 – Tergiver

+0

@Guapo第三次的魅力。 – Tergiver

0

那么,如果你至少需要4个不同的地方,你至少需要四个点。你分两部分来做 - 首先选择最后得到一个点的4个单词(即,随机选择一个单词,为它添加一个点,并确保你不再选择它),然后选择3随机发言,重复,并添加点。

+0

那么我不想做几个循环来完成这个任务,这就是为什么我正在寻找替代品或者可以做到这一点的漂亮的LINQ。 – Guapo

+0

你只需要两个循环。我怀疑你可以让LINQ表达式比两个循环更具可读性(在这种情况下,当然不是每一种情况)。 – zmbq

+0

嗯,我已经设法做到了主'for',但仍然看起来没有吸引力,这就是为什么可能用LINQ,所以我想。 – Guapo

0

只是为了好玩和简洁,我可以把它:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Text.RegularExpressions; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var random = new Random(); 

      var iTemplate = "Hi, this is a template with several words on it and I want to place random dots on 4 different random places every time I run the function";  
      var result = iTemplate; 

      while (new Regex("\\. ").Matches(result).Count < 4) 
       result = result.TrimEnd() 
        .Split(' ') 
        .Aggregate(
         string.Empty, 
         (current, word) => 
          current + (word + (((word.EndsWith(".") || (random.Next(1, 100) % 10) != 0)) ? "" : new string('.', random.Next(1, 7))) + " ") 
         ); 

      Console.WriteLine(result); 
      Console.Read(); 
     } 
    } 
} 
+0

看起来很有趣,但中间的“while和regex”并不能让我喜欢它。我会揣摩你的想法,看看我能不能拿出一些东西。 – Guapo

+0

Twas只是为了好玩,但它的作品...它使用Linq的东西,这是有趣的:) –

相关问题