如何在按钮之间平均分割字符串的字符?
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 指向正确的方向,您实际上可以引导他/她。您对代码的解释为零,并且代码有错误。以上是关于如何在按钮之间平均分割字符串的字符?的主要内容,如果未能解决你的问题,请参考以下文章