循环以检查重复的字符串

时间:2018-01-30 14:50:40

标签: c# loops foreach

我想创建一个循环来检查重复项的标题列表。

我目前有这个:

template <typename T>
int main()
{
    Calculator<T> calc;
    bool flag = true;
    int punto = 0;
    string entry, op;
    T a, b, r;
    entry = ' ';
    while (flag) {
        try {
            cin << op;
            entry += op;
            for (int i = 0; i < entry.length(); i++) {
                if (entry[i] == '+' || entry[i] == '-' || entry[i] == '*' || entry[i] == '/') {
                    for (int j = 0; j < i; j++) {
                        if (entry[j].isdigit) {
                            a += entry[j];
                        }
                        else if (entry[j] == '.') {
                             a += entry[j];
                             punto++;
                             if (punto > 1) {
                                 throw '.';
                             }
                         }
                        else{
                            throw "l";
                        }

                    }
                    if (punto = 1) {
                        a = stof(a);
                    }
                    else {
                        a = stoi(a);
                    }

但这是我从数组中跳过下一个循环的项目,因此第2项从不检查它与项目1相同,它直接移动到第3项。

我的印象是,skip只是传递了你传入的索引而不是从列表中删除它。

4 个答案:

答案 0 :(得分:4)

您可以使用GroupBy

max(pixel_histogram)

Distinct

var anyDuplicates = SeleniumContext
    .Driver
    .FindElements(By.XPath(ComparisonTableElements.ProductTitle))
    .GroupBy(p => p.Text, p => p)
    .Any(g => g.Count() > 1);

Assert.That(anyDuplicates, Is.False);

或者,如果只是找到第一个副本而不计算所有副本就足够了,那么最好使用HashSet<T>

var productTitles = SeleniumContext
    .Driver
    .FindElements(By.XPath(ComparisonTableElements.ProductTitle))
    .Select(p => p.Text)
    .ToArray();

var distinctProductTitles = productTitles.Distinct().ToArray();

Assert.AreEqual(productTitles.Length, distinctProductTitles.Length);

所有方法在计算复杂度(O(n))方面都优于您提出的方法(O(n 2 ))。

答案 1 :(得分:2)

您不需要循环。只需使用Where()函数查找所有相同的标题,如果有多个标题,则它们是重复的:

var productTitles = SeleniumContext.Driver.FindElements(By.XPath(ComparisonTableElements.ProductTitle));

foreach(var x in productTitles) {
  if (productTitles.Where(y => x.Text == y.Text).Count() > 1) {
    Assert.Fail("Found duplicate product in the table");
  }
}

答案 2 :(得分:1)

我会尝试稍微不同的方式,因为您只需要检查一维数组中的重复项。

您只需要使用数组/集合中的下一个元素检查前一个元素,因此使用Linq迭代所有项目似乎有点不必要。

这是一段更好理解的代码:

var productTitles = SeleniumContext.Driver.FindElements(By.XPath(ComparisonTableElements.ProductTitle))

for ( int i = 0; i < productionTitles.Length; i++ )
{
    var currentObject = productionTitles[i];
    for ( int j = i + 1; j < productionTitles.Length; j++ )
    {
        if ( currentObject.Title == productionTitles[j].Title )
        {
            // here's your duplicate
        }
    }
}

由于您已检查索引0处的项目与索引3处的项目不同,因此当您在索引3处时,无需再次检查该项目。这些项目将保留同样的。

答案 3 :(得分:0)

Skip(IEnumerable, n)方法返回一个IEnumerable,它不包含&#34;#34;包含&#34;它被调用的IEnumerable的第一个元素。

此外,我不知道这会产生什么样的行为,但我不会将新的IEnumerable分配给正在执行foreach的变量。

这是LINQ的另一个可能的解决方案:

int i = 0;
foreach (var x in productTitles)
{
    var possibleDuplicate = productTitles.Skip(i++).Find((y) => y.title == x.title);

    //if possibleDuplicate is not default value of type
        //do stuff here
}

毋庸置疑,但最适合您的解决方案将取决于您的目标。此外,我认为Skip方法调用比它的价值更麻烦,因为我非常肯定它肯定会使搜索效率降低。