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

Posted

技术标签:

【中文标题】如何在按钮之间平均分割字符串的字符?【英文标题】:How to split characters of string equally between buttons? 【发布时间】:2019-12-17 11:47:35 【问题描述】:

我有一个包含各种单词的字符串元素数组。我需要将每个单词的字符平均分成 3 个按钮的文本组件。例如,数组可以保存元素"maybe", "his", "car"。在每个游戏中,这些单词中的一个将从数组中提取,并将其字符分为 3 个按钮。例如,按钮 1 将具有 "ma",按钮 2 将具有 "yb" 和按钮 3 "e"(对于单词可能)。然后我隐藏一个按钮的文本元素,以便用户将正确的缺失字母拖放到空间中。游戏的目的是帮助孩子们学习拼写。有谁知道我如何将字符平均分为 3 个按钮?

【问题讨论】:

你的划分标准是什么?如果单词长度少于 3 个字符怎么办?如果长于3,你想怎么分割? 【参考方案1】:

这是一个函数,可以将单词分割成你想要的段数。然后,您可以遍历该列表以将每个段设置为 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;

用法:

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

编辑

我喜欢这是为了教孩子。所以来了。 关于根据特定字母序列拆分字符串的问题:使用正则表达式拆分字符串后,您将拥有一个字符串数组。然后确定拆分字符串中的项目数量,并根据段数进一步连接或拆分:

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

【讨论】:

非常感谢您的帮助。我刚刚尝试了你的代码,它奏效了!谢谢你。我也刚刚想到了一些东西....我将首先使用 Regex.Split() 拆分单词....即,如果单词包含特定的 2 个相邻字母,我将对其进行拆分。你知道我如何将字符串数组传递给函数吗? 谢谢@JessedeWit。我有点困惑如何为数组的每次迭代调用函数:/如果数组的第一个元素包含 2 个字符,该函数会尝试将其拆分为 3 段? @Lloyd SplitWord 现在总是返回三个段 ;-) @Lloyd 请注意,如果您将此标记为答案,我将不胜感激。 让我们continue our discussion in chat【参考方案2】:

这是另一种方法。

首先确保单词可以被所需的段分割(如果需要,添加一个虚拟空格),然后使用 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();

【讨论】:

如果您将“maybe”分成 4 段,您的代码输出 ["ma", "yb", "e", ""],我希望 ["ma", " y", "b", "e"] (虽然我知道这不是问题,但函数签名表明这是可能的)【参考方案3】:

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

字符串测试 = “也许”; List list = new 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

【讨论】:

如果字长为 8 则生成异常,如果字长为 9 则分为 3 个以上。请在发布前测试您的解决方案。 A downvote for this is a bit harsh, TBH 我不认为你提到的那样; the OP is not even providing what they have tried,当没有no 详细信息时,为什么要在帖子中首先发布答案。 OP 寻求帮助,但没有提供详细信息供我们帮助,但我们这里有一个解决方案也不起作用,您的想法是什么? @Çöđěxěŕ 考虑到 OP 没有提供任何代码,我确实认为这有点苛刻。目的是指出一个方向,以便他们可以根据示例/想法进行实际工作。毕竟我们不是来提供编码服务的!!!还是谢谢! @Sach SO 不是编码服务,但我们随时为您提供帮助。感谢您的低调! 不完整和错误的代码无济于事。如果您想将 OP 指向正确的方向,您实际上可以引导他/她。您对代码的解释为零,并且代码有错误。

以上是关于如何在按钮之间平均分割字符串的字符?的主要内容,如果未能解决你的问题,请参考以下文章

如何在每个字符串之间用逗号分割数组?

在空格处分割R字符串,但当空格在单引号之间时不分割

PHP:用逗号分割字符串,但不是在大括号或引号之间?

字符串分割split()

如何用空格分割字符串,不包括Python中双引号之间的空格? [复制]

js如何使用指定字符分割字符串