1

好的,这是我遇到的问题:使用 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]);
            }
}

谢谢。


感谢你们提供各种出色的解决方案,非常感谢您的帮助!谢谢!

4

5 回答 5

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毫秒)

 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();
}
于 2013-06-02T11:18:48.877 回答
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

于 2013-06-02T11:26:05.663 回答
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());
于 2013-06-02T11:21:05.843 回答
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();
}
于 2013-06-02T11:39:52.507 回答
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());
于 2013-06-02T11:32:25.617 回答