1

I want to insert a random amount of dots (from 1 to 7) on random parts of a string without breaking the layout.

This is my current code:

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 + " ";
}

Is there a more efficient or nice LINQ option to it ?

Right now, since its random, there may be cases of no dots showing up. I have narrowed it by using if (rand.Next(i, words.Count()) == i) which seems to work but still some results only show 1 to 3 places having dots inserted.

How could I guarantee that the dots are inserted a minimum of 4 different places during the process ?

Sample data/result as per comment request:

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";

Result 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";

Result 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";

Result 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";
4

4 に答える 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;
        }
    }
}
于 2012-06-07T16:33:42.127 に答える
0

少なくとも 4 つの異なる場所が必要な場合は、少なくとも 4 つのドットが必要です。あなたはそれを2つの部分で行います - 最初に最後にドットを得る4つの単語を選択してください(つまり、単語をランダムに選択し、それにドットを追加し、それを再び選択しないようにしてください)、次に3つを選択します単語をランダムに繰り返し、それらにドットを追加します。

于 2012-06-07T16:39:44.453 に答える
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();
        }
    }
}
于 2012-06-07T16:45:15.503 に答える
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 つの単語があることを前提としています。そうしない可能性がある場合は、検証ロジックを追加する必要があります。

于 2012-06-07T16:52:59.157 に答える