5

我有两个长度相等(<=500)的字符串(带有 1 和 0),并且想对这些字符串应用逻辑 OR。

我应该如何处理这个问题。我正在使用 c#。

当我考虑明显的解决方案时,阅读每个字符并应用 OR | 在他们身上,我必须处理 apx,250000 个字符串,每个字符串的长度为 500。这会扼杀我的表现。

性能是我主要关心的问题。

提前致谢!

4

5 回答 5

4

这是最快的方法:

string x="";
string y="";
StringBuilder sb = new StringBuilder(x.Length);
for (int i = 0; i < x.Length;i++ )
{
    sb.Append(x[i] == '1' || y[i] == '1' ? '1' : '0');
}
string result = sb.ToString();
于 2016-03-06T12:06:42.830 回答
3

由于提到速度是一个重要因素,因此最好使用按位运算。

看一下ASCII 表

  • 字符'0'0x30, 或00110000二进制。
  • 字符'1'0x31, 或00110001二进制。

只有字符的最后一位不同。因此——我们可以肯定地说,对字符本身执行按位或运算将产生正确的字符。

我们可以做的另一件重要的事情是优化速度是使用StringBuilder, 初始化为我们字符串的初始容量。甚至更好:我们可以重复使用我们StringBuilder的多个操作,尽管我们必须确保StringBuilder有足够的容量。

考虑到这些优化,我们可以制作这个方法:

string BinaryStringBitwiseOR(string a, string b, StringBuilder stringBuilder = null)
{
    if (a.Length != b.Length)
    {
        throw new ArgumentException("The length of given string parameters didn't match");
    }

    if (stringBuilder == null)
    {
        stringBuilder = new StringBuilder(a.Length);
    }
    else
    {
        stringBuilder.Clear().EnsureCapacity(a.Length);
    }

    for (int i = 0; i < a.Length; i++)
    {
        stringBuilder.Append((char)(a[i] | b[i]));
    }
    return stringBuilder.ToString();
}

请注意,这将适用于您希望对字符串执行的所有按位操作,您只需修改|运算符。

于 2016-03-06T13:03:53.983 回答
2

我有两个长度相等(<=500)的字符串(带有 1 和 0),并且想对这些字符串应用逻辑 OR。

您可以编写自定义逻辑 OR 运算符或函数,将两个字符作为输入并产生结果(例如,如果输入字符中的至少一个为“1”,则返回“1”,否则返回“0”)。将此函数应用于字符串中的每个字符。

你也可以看看这个方法。您首先需要将每个字符转换为布尔值(例如,'1' 对应于 true),在两个布尔值之间执行 OR 运算,将结果转换回字符 '0' 或 '1' - 取决于逻辑 OR 的结果是否为 false或分别为真。然后只需将此操作的每个结果附加到彼此。

于 2016-03-06T12:02:42.683 回答
2

我发现这比所有提议的解决方案都要快。它结合了@Gediminas 和@Sakura 答案中的元素,但使用预初始化char[]而不是StringBuilder.

虽然StringBuilder在内存管理方面很有效,但每个Append操作都需要对标记进行一些记账,并且执行的操作比仅索引到数组中的操作更多。

string x = ...
string y = ...
char[] c = new char[x.Length];
for (int i = 0; i < x.Length; i++)
{
    c[i] = (char)(x[i] | y[i]);
}
string result = new string(c);
于 2016-03-06T13:19:08.837 回答
1

您可以使用Linq查询压缩然后汇总结果:

var a = "110010";    
var b = "001110";  
var result = a.Zip(b, (i, j) => i == '1' || j == '1' ? '1' : '0')
              .Select(i => i + "").Aggregate((i, j) => i + j);

基本上,Zip扩展方法采用两个序列并对两个序列的每个对应元素应用一个操作。然后我使用Selectcharto 转换String,最后我将结果从一系列字符串(“0”和“1”)聚合到一个字符串。

于 2016-03-06T12:20:05.380 回答