好的,这就是我遇到的问题:使用C#我想通过打印一定数量的字符来格式化字符串,然后跳过一定数量的字符然后再打印,跳过。
例如:我想通过跳过下一个2来打印3个字符。
所以这个:
ABCDEFGHIJKL
会变成这样: ABCFGHKL
我只是说它可以跳过每2,3,4等角色,我想不出如何进一步解决这个问题。
到目前为止,我有什么
string text;
int print = 3;
int skip = 2;
StreamReader file = new StreamReader(@"c:\test.txt");
while ((text = file.Readtext()) != null)
{
string[] stringArray = new string[text.Length];
char ch;
for (int i = 0; i < text.Length; i++)
{
ch = text[i];
stringArray[i] = ch.ToString();
}
for (int i = 0; i < stringArray.Length; i+=skip)
{
Console.Write(stringArray[i]);
}
}
感谢。
感谢大家提供各种出色的解决方案,非常感谢您的帮助!谢谢!
答案 0 :(得分:2)
int take = 3;
int skip = 2;
string s = "ABCDEFGHIJKL";
var newstr = String.Join("", s.Where((c,i) => i % (skip + take) < take));
修改强>
以下是我的测试结果......
int take = 3;
int skip = 2;
string s = String.Join("",Enumerable.Repeat("0123456789", 200));
var t1 = Measure(10000, () => { var newstr = String.Join("", s.Where((c, i) => i % (skip + take) < take)); });
var t2 = Measure(10000, () => { var newstr = new string(s.Where((c, i) => i % (skip + take) < take).ToArray()); });
var t3 = Measure(10000, () => { var newstr = GetString(s, take, skip); });
long Measure(int n,Action action)
{
action(); //JIT???
var sw = Stopwatch.StartNew();
for (int i = 0; i < n; i++)
{
action();
}
return sw.ElapsedMilliseconds;
}
<强>输出:强>
1665 ms. (String.Join)
1154 ms. (new string())
7457 ms. (Sayse's GetString)
编辑2
修改Sayse的答案如下所示,我测试的代码中的结果最快。 ( 311 ms)
public string GetString(string s, int substringLen, int skipCount)
{
StringBuilder newString = new StringBuilder(s.Length);
for (int i = 0; i < s.Length; i += skipCount)
{
for (int j = 0; j < substringLen && i < s.Length; j++)
{
newString.Append(s[i++]);
}
}
return newString.ToString();
}
答案 1 :(得分:1)
我更喜欢I4V的答案,但这是实现这一目标的一种方法
public string GetString(string s, int substringLen, int skipCount)
{
string newString = "";
for (int i = 0; i < s.Length; i += skipCount)
{
for (int j = 0; j < substringLen && i < s.Length; j++)
{
newString += s[i++];
}
}
return newString;
}
编辑基准测试表明我的方式更快
var newStr2 = new Program().GetString(a, take, skip);
var newstr = String.Join("", a.Where((c, i) => i % (skip + take) < take));
sw.Start();
for (int i = 0; i < 1000000; i++)
{
newStr2 = new Program().GetString(a, take, skip);
}
sw.Stop();
Console.WriteLine("my way: " + sw.Elapsed.ToString());
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000; i++)
{
newstr = String.Join("", a.Where((c, iv) => iv % (skip + take) < take));
}
sw.Stop();
Console.WriteLine("I4V way: " + sw.Elapsed.ToString());
输出
我的方式:00:00:00.7634927
I4V方式:00:00:01.0183307
答案 2 :(得分:0)
这是怎么做到的。 如果您不熟悉Lambda表达式,我认为这可能会更清楚
int print = 3;
int skip = 2;
string str = "ABCDEFGHILKL";
StringBuilder stringBuilder = new StringBuilder();
string res = String.Empty;
int i = 0;
while (i < str.Length)
{
stringBuilder.Append(str.Substring(i, Math.Min(print, str.Length - i)));
i += print + skip;
}
Console.WriteLine(stringBuilder.ToString());
答案 3 :(得分:0)
int print = 3;
int skip = 2;
Boolean isPrintState = true;
int statePosition = 0;
StringBuilder Sb = new StringBuilder();
using (TextReader reader = new StreamReader(@"c:\test.txt")) {
while (true) {
int Ch = reader.Read();
if (Ch < 0)
break;
statePosition += 1;
if ((isPrintState && (statePosition > print)) || (!isPrintState && (statePosition > skip))) {
statePosition = 1;
isPrintState = !isPrintState;
}
if (isPrintState)
Sb.Append((Char) Ch);
}
}
Console.Write(Sb.ToString());
答案 4 :(得分:0)
在如此多的好看的答案中,我可能不会那么复杂,但我想我会发布它。简单的逻辑。
var take = 3;
var skip = 2;
StringBuilder source = new StringBuilder("ABCDEFGHIJKL");
StringBuilder result = new StringBuilder();
while (source.Length > 0)
{
if (source.Length >= take)
{
result.Append(source.ToString().Substring(0, take));
}
else
{
result.Append(source.ToString());
}
if (source.Length > skip + take)
{
source.Remove(0, skip + take);
}
else
source.Clear();
}