簡體   English   中英

快速比較相同字符串數組的元素

[英]Compare elements of same string array quickly

編輯:我認為 C# 編譯器或網站上出現了問題,我不知道如何使它比最終獲得項目更快。 我切換到 Java 並且工作正常,與 C# 項目的邏輯完全相同。

using System;

namespace ConsoleApp1
{
class Program
{
    static void Main(string[] args)
    {
        int testCases = int.Parse(Console.ReadLine());
        while (testCases > 0)
        {
            int nNum = int.Parse(Console.ReadLine()); //Needed num version for validation
            string[] numbers = new string[nNum];
            for (int j = 0; j < numbers.Length; j++)               
                numbers[j] = Console.ReadLine(); //This fills array with numbers                
            Array.Sort(numbers); //Sorts string array
            bool consistent = true; //Checking whether we detect any 'inconsistencies'
            for (int j = 0; j < numbers.Length - 1; j++)
            {
                if (numbers[j+1].StartsWith(numbers[j]))
                {
                    consistent = false;
                    break;
                }

            }
            Console.WriteLine(consistent ? "YES" : "NO");
            testCases--;
        }

    }
}
}

這是 C# 的最終代碼。 無論我做什么,它都保持在 3 秒以上。

原始問題:我要快點——我有這個任務,我得到 1-10000 個唯一的電話號碼。 我必須檢查數組中的一個號碼是否是另一個號碼的前綴,即'911',是一個電話號碼,'911859285'是另一個號碼,但是,我必須打印它“不是一個一致的列表”,因為第二個號碼的前綴是第一個號碼。

我最初的想法是嵌套的 for 循環......你可以看到這是一個絕對糟糕的想法,考慮到我必須測試 1 億次比較。 我嘗試了一個 bool 來打破這個嵌套循環,但后來意識到如果確實所有數字都有效,那么我們仍然遇到了問題。

tl;dr - 我需要一種快速的方法來比較 1-10000 個元素的字符串數組中的元素。 如果一個字符串是另一個字符串的開頭,則它是無效的數字列表。

我見過很多不同的東西,比如 SequenceEquals 和 LINQ 表達式,但我決定來這里尋求專業幫助。

更新代碼

using System;

namespace ConsoleApp1
{
    class Program
    {
    static void Main(string[] args)
    {
        bool validTestNum = false;
        int testCases = 0;
        try
        {
            testCases = int.Parse(Console.ReadLine());
            validTestNum = true;
            if (testCases < 1 || testCases > 40)
            {
                validTestNum = false;
            }
        }
        catch { }

        for (int i = 0; i < testCases; i++)
        {
            bool validN = false;
            string nString = ""; //Needed string 
            int nNum = 0; //Needed num version for validation
            while (!validN)
            {
                nNum = int.Parse(Console.ReadLine());
                validN = true;
                if (nNum < 1 || nNum > 10000)
                    validN = false; //This is validating the amount of phone numbers received
            }

            nString = nNum.ToString();
            string[] numbers = new string[int.Parse(nString)];
            for (int j = 0; j < numbers.Length; j++)
            {
                numbers[j] = Console.ReadLine(); //This fills array with numbers
            }

            bool consistent = true; //Checking whether we detect any 'inconsistencies'
            Array.Sort(numbers); //Sorts string array

            for (int j = 1; j < numbers.Length; j++)
            {
                string possiblePrefix = numbers[j - 1];
                if (j < numbers.Length && numbers[j].StartsWith(possiblePrefix))
                {
                    consistent = false;
                    break;
                }
            }

            if (consistent)
            {
                Console.WriteLine("YES"); //Means the list is consistent
            }
            else if (!consistent)
            {
                Console.WriteLine("NO"); //Means it isn't
            }
        }
        Console.ReadLine();

    }
}

}

對數組進行排序。 像“911”這樣的較短數字將始終位於它所屬的任何較長數字之前。 排序列表示例:

910123407
911
911859285
911859286
912348745

因此,您所要做的就是檢查給定數字是否是下一個數字的開始。 你可以盡快停止。

Array.Sort(a);
for (int i = 1; i < a.Length; i++) { // Note: we start at index 1, not 0
    string possiblePrefix = a[i - 1];
    for (int k = i; k < a.Length && a[k].StartsWith(possiblePrefix); k++) {
        // a[k] is inconsistent with possiblePrefix , add it to a list or whatever.
        Console.WriteLine($"{possiblePrefix} - {a[k]}");
    }
}

請注意,對於大多數數字,內部循環甚至不會開始循環。 只有在發現不一致的極少數情況下,它才會循環。 所以,這是一個接近O(n)的算法。 排序是一個O(n log(n))操作。

如果您只需要知道系列的第一個不一致性,您也可以用簡單的if替換內部循環。

這是一個LINQ解決方案,如果你想 go 那個路徑:

static void Main(string[] args)
{
    var list = new List<string>
    {
        "1",
        "23",
        "456",
        "7890",
        "23457"
    };

    var prefixFound = false;
    foreach (var num in list)
    {
        if (list.Any(x => x.StartsWith(num) && x != num))
        {
            prefixFound = true;
            Console.WriteLine(num);
            break;
        }
    }
    if (!prefixFound)
        Console.WriteLine("Consistent list.");

    Console.ReadLine();
}

&& x != num條件是排除技術上數字以自身開頭的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM