如何在按钮之间平均分割字符串字符?

时间:2019-08-09 17:56:23

标签: c# arrays string unity3d split

我有一个由多个单词组成的字符串元素数组。我需要将每个单词的字符平均分为3个按钮的文本部分。例如,该数组可以包含元素"maybe", "his", "car"。在每个游戏中,这些单词中的一个将从数组中拉出,其角色分为3个按钮。例如,按钮1将具有"ma",按钮2将具有"yb",按钮3将具有"e"(可能是单词)。然后,我隐藏了一个按钮的文本元素,以供用户将正确的丢失字母拖放到该空格中。游戏的目的是帮助孩子学习拼写。有谁知道我该如何将字符平均分成3个按钮?

3 个答案:

答案 0 :(得分:3)

这是一个将单词拆分为所需分段数量的功能。然后,您可以遍历该列表以将每个段设置为一个按钮。

public List<string> SplitInSegments(string word, int segments)
{
    int wordLength = word.Length;

    // The remainder tells us how many segments will get an extra letter
    int remainder = wordLength % segments;

    // The base length of a segment
    // This is a floor division, because we're dividing ints.
    // So 5 / 3 = 1
    int segmentLength = wordLength / segments;

    var result = new List<string>();
    int startIndex = 0;
    for (int i = 0; i < segments; i++)
    {
        // This segment may get an extra letter, if its index is smaller then the remainder
        int currentSegmentLength = segmentLength + (i < remainder ? 1 : 0);

        string currentSegment = word.Substring(startIndex, currentSegmentLength);

        // Set the startindex for the next segment.
        startIndex += currentSegmentLength;

        result.Add(currentSegment);
    }

    return result;
}

用法:

// returns ["ma", "yb", "e"]
var segments = SplitInSegments("maybe", 3);

编辑

我喜欢这样的事实,那就是教孩子们。所以来了。 关于根据特定字母序列拆分字符串的问题:使用regex拆分字符串后,将有一个字符串数组。然后确定分割后的字符串中的项目数量,并根据段数进一步串联或分割:

// sequences to split on first
static readonly string[] splitSequences = {
    "el",
    "ol",
    "bo"
};

static readonly string regexDelimiters = string.Join('|', splitSequences.Select(s => "(" + s + ")"));

// Method to split on sequences
public static List<string> SplitOnSequences(string word)
{
    return Regex.Split(word, regexDelimiters).Where(s => !string.IsNullOrEmpty(s)).ToList();
}

public static List<string> SplitInSegments(string word, int segments)
{
    int wordLength = word.Length;

    // The remainder tells us how many segments will get an extra letter
    int remainder = wordLength % segments;

    // The base length of a segment
    // This is a floor division, because we're dividing ints.
    // So 5 / 3 = 1
    int segmentLength = wordLength / segments;

    var result = new List<string>();
    int startIndex = 0;
    for (int i = 0; i < segments; i++)
    {
        // This segment may get an extra letter, if its index is smaller then the remainder
        int currentSegmentLength = segmentLength + (i < remainder ? 1 : 0);

        string currentSegment = word.Substring(startIndex, currentSegmentLength);

        // Set the startindex for the next segment.
        startIndex += currentSegmentLength;

        result.Add(currentSegment);
    }

    return result;
}

// Splitword will now always return 3 segments
public static List<string> SplitWord(string word)
{
    if (word == null)
    {
        throw new ArgumentNullException(nameof(word));
    }

    if (word.Length < 3)
    {
        throw new ArgumentException("Word must be at least 3 characters long", nameof(word));
    }

    var splitted = SplitOnSequences(word);

    var result = new List<string>();
    if (splitted.Count == 1)
    {
        // If the result is not splitted, just split it evenly.
        result = SplitInSegments(word, 3);
    }
    else if (splitted.Count == 2)
    {
        // If we've got 2 segments, split the shortest segment again.
        if (splitted[1].Length > splitted[0].Length
            && !splitSequences.Contains(splitted[1]))
        {
            result.Add(splitted[0]);
            result.AddRange(SplitInSegments(splitted[1], 2));
        }
        else
        {
            result.AddRange(SplitInSegments(splitted[0], 2));
            result.Add(splitted[1]);
        }
    }
    else // splitted.Count >= 3
    { 
        // 3 segments is good.
        result = splitted;

        // More than 3 segments, combine some together.
        while (result.Count > 3)
        {
            // Find the shortest combination of two segments
            int shortestComboCount = int.MaxValue;
            int shortestComboIndex = 0;
            for (int i = 0; i < result.Count - 1; i++)
            {
                int currentComboCount = result[i].Length + result[i + 1].Length;
                if (currentComboCount < shortestComboCount)
                {
                    shortestComboCount = currentComboCount;
                    shortestComboIndex = i;
                }
            }

            // Combine the shortest segments and replace in the result.
            string combo = result[shortestComboIndex] + result[shortestComboIndex + 1];
            result.RemoveAt(shortestComboIndex + 1);
            result[shortestComboIndex] = combo;
        }
    }

    return result;
}

现在,当您调用代码时:

// always returns three segments.
var splitted = SplitWord(word);

答案 1 :(得分:1)

这是另一种方法。

首先请确保可以将单词除以所需的句段(如有必要,请添加一个虚拟空格),然后使用Linq语句获取所需的部分,并在添加结果时删除虚拟字符。

public static string[] SplitInSegments(string word, int segments)
{
    while(word.Length %  segments != 0) { word+=" ";}
    var result = new List<string>();
    for(int x=0; x < word.Count(); x += word.Length / segments)
    result.Add((new string(word.Skip(x).Take(word.Length / segments).ToArray()).Trim()));
    return result.ToArray();
}

答案 2 :(得分:-2)

您可以将字符串分成一个列表,并根据列表生成按钮。将单词拆分为字符串列表的逻辑类似于以下内容:

string test =“也许”;         列表列表=新的List();

    int i = 0, len = 2;
    while(i <= test.Length)
    {
        int lastIndex = test.Length - 1;
        list.Add(test.Substring(i, i + len > lastIndex? (i + len) - test.Length : len));
        i += len;       
    }

HTH