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

C# 如何在按钮之间平均分割字符串的字符?,c#,arrays,string,unity3d,split,C#,Arrays,String,Unity3d,Split,我有一个由不同单词组成的字符串元素数组。我需要将每个单词的字符平均分为3个按钮的文本部分。例如,数组可以包含元素“maybe”、“his”、“car”。在每一个游戏中,这些单词中的一个将从数组中提取出来,其角色被分成3个按钮。例如,按钮1将有“ma”,按钮2将有“yb”和按钮3“e”(对于单词maybe)。然后我隐藏一个按钮的文本元素,以便用户将正确的缺失字母拖放到空格中。这个游戏的目的是帮助孩子们学习拼写。有人知道我如何将字符平均分为3个按钮吗?您可以将字符串分为一个列表,并根据列表生成按钮。

我有一个由不同单词组成的字符串元素数组。我需要将每个单词的字符平均分为3个按钮的文本部分。例如,数组可以包含元素
“maybe”、“his”、“car”
。在每一个游戏中,这些单词中的一个将从数组中提取出来,其角色被分成3个按钮。例如,按钮1将有
“ma”
,按钮2将有
“yb”
和按钮3
“e”
(对于单词maybe)。然后我隐藏一个按钮的文本元素,以便用户将正确的缺失字母拖放到空格中。这个游戏的目的是帮助孩子们学习拼写。有人知道我如何将字符平均分为3个按钮吗?

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

string test=“maybe”; 列表=新列表()

inti=0,len=2;
而(i lastIndex?(i+len)-测试长度:len);
i+=len;
}

HTH

这里有一个函数,可以将单词分割成您想要的段数。然后可以迭代该列表,将每个段设置为button.Text

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;
}
编辑 我喜欢这样的事实,这是为了教孩子们。来了。 关于您关于基于特定字母序列拆分字符串的问题:使用正则表达式拆分字符串后,您将拥有一个字符串数组。然后确定拆分字符串中的项目数量,并根据段数进一步连接或拆分:

// 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;
}

这是另一种方法

首先确保单词可以被所需的段分割(如有必要,添加一个虚拟空格),然后使用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();
}
公共静态字符串[]拆分插入段(字符串字、整数段)
{
而(word.Length%segments!=0){word+=“”;}
var result=新列表();
对于(int x=0;x
您的划分标准是什么?如果单词长度少于3个字符怎么办?如果长度大于3,您希望如何分割它?如果单词长度为8,则会生成异常,如果长度为9,则会分割为3以上。请在发布前测试您的解决方案。
对此的否决票有点苛刻
,TBH我认为这并不像您提到的那样
OP甚至没有提供他们尝试过的内容
,为什么在没有详细信息的情况下,你会首先将答案发布到帖子上。OP请求帮助,但没有提供详细的帮助,但我们这里有一个解决方案也不起作用,你的想法是什么?@đěxěŕ考虑到OP没有提供任何代码,我确实觉得有点苛刻。目的是指出一个方向,以便他们能够根据示例/想法进行实际工作。毕竟,我们不是来提供编码服务的!!!无论如何谢谢你@Sach SO不是一个编码服务,但我们在这里提供帮助。谢谢你的谈话!不完整和错误的代码没有帮助。如果你想给OP指出正确的方向,你可以指导他/她。您的代码没有任何解释,并且代码有错误。非常感谢您的帮助。我刚刚试用了你的代码,效果不错!非常感谢。我也刚刚想到了一件事。。。。我将首先使用Regex.Split()拆分单词。。。。i、 如果这个词包含两个相邻的字母,我就把它拆分。你知道如何将字符串数组传递给函数吗?谢谢@JessedeWit。我对为数组的每次迭代调用函数的方式有点困惑:/如果数组的第一个元素包含2个字符,函数会尝试将其拆分为3个段?@Lloyd SplitWord现在总是返回三个段;-)@劳埃德注意到,如果您能将此标记为答案,我将不胜感激。让我们看看,如果您将“maybe”分为4段,您的代码输出[“ma”、“yb”、“e”、“”],我希望[“ma”、“y”、“b”、“e”](虽然我知道这不是问题,但函数签名表明这是可能的)
// 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);
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();
}