2016-07-18 51 views
2

數組既然已經瞭解了基本知識/ C#編程語言的基礎,我現在正試圖解決我的第一個實際問題:寫一個程序,給定一個字符串,認定其包含至少一個大寫字母沒有數字最長子串(並隨後顯示該最長子串的長度)。這可能是兩個對於可接受的密碼預選賽條件,例如...檢查兩個條件同時遍歷字符

我已經寫了下面的所有代碼由我自己,這意味着可能存在性能問題,但這是以後考慮。我被困在我必須確保子字符串中沒有數字的地方。在我的代碼中的註釋說明了我的思維,而寫程序...

我想首先我應該檢查,看看是否有在抽取的子串的大寫字母,如果有,那麼我就可以將該合格的子字符串存儲在列表中,然後跳出循環。但是現在我想知道如何在同一個子字符串中同時檢查無數字狀態?

我試圖保持它整潔和簡單(正如我所說,我剛剛開始編寫超過幾行的程序!),所以我想做一個嵌套循環檢查每個字符!char.IsNumber(letter)可能不是最佳。或者我應該先檢查一下是否沒有數字,然後看看是否至少有一個大寫字母?

我感到困惑如何實現這兩個限制,所以我希望在解決這個問題提供一些幫助。我也希望任何意見或你可能有建議。例如,是否可以將我的子字符串存儲在列表中?我應該編一本什麼字典嗎?我所有可能的子字符串提取嵌套循環是最優的嗎?

附:有些位仍未完成;例如我仍然執行最後一步找到最長的子字符串,並顯示給用戶的長度...

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace PasswordRestriction 
{ 
    class Program /// Write a program that, given a string, finds the longest substring that is a valid password and returns its length. 
    { 
     static void Main(string[] args) 
     { 
      // Ask the user for an alphanumeric string. 
      Console.WriteLine("Enter a string of alphanumeric values:"); 

      // Receive the user input as string. 
      string password = Console.ReadLine(); 

      // Print the length of the longest qualifying substring of the user string. 
      Console.WriteLine("Length of the longest qualifying substring:\n" + Solution(password).Length); 

      // Prevent the console window from closing. 
      Console.ReadLine(); 
     } 


     /// The method that exracts the longest substring that is a valid password. 
     /// Note that a substring is a 'contiguous' segment of a string. 
     public static string Solution(string str) 
     { 
      // Only allow non-empty strings. 
      if (String.IsNullOrEmpty(str)) 
      { 
       return ""; 
      } 
      else 
      { 
       // Only allow letters and digits. 
       if (str.All(char.IsLetterOrDigit)) 
       { 
        // A list for containing qualifying substrings. 
        List<string> passwordList = new List<string>(); 

        // Generate all possible substrings. Note that 
        // string itself is not a substring of itself! 
        for (int i = 1; i < str.Length; i++) 
        { 
         for (int j = 0; j <= (str.Length-i); j++) 
         { 
          string subStr = str.Substring(j, i); 
          Console.WriteLine(subStr); 

          bool containsNum = false; 
          bool containsUpper = false; 

          // Convert the substrings to arrays of characters with ToCharArray. 
          // This method is called on a string and returns a new character array. 
          // You can manipulate this array in-place, which you cannot do with a string. 
          char[] subStrArray = subStr.ToCharArray(); 

          // Go through every character in each substring. 
          // If there is at least one uppercase letter and 
          // no digits, put the qualifying substring in a list. 
          for (int k = 0; k < subStrArray.Length; k++) 
          { 
           char letter = subStrArray[k]; 

           if (char.IsNumber(letter)) 
           { 
            containsNum = true; 
            break; 
           } 

           if (char.IsUpper(letter)) 
           { 
            containsUpper = true; 
           } 

           if (containsUpper && (containsNum == false) && (k == subStrArray.Length - 1)) 
           { 
            Console.WriteLine("Found the above legit password!"); 
            passwordList.Add(subStr); 
           } 
          } 
         } 
        } 

        //Find the longest stored string in the list. 
        //if (passwordList.Count != 0) 
        //{ 
         string maxLength = passwordList[0]; 

         foreach (string s in passwordList) 
         { 
          if (s.Length > maxLength.Length) 
          { 
           maxLength = s; 
          } 
         } 
        //} 

        // Return the qualifying substring. 
        return maxLength; 
       } 
       else 
       { 
        return "aaaaaaaaaa"; 
       } 
      } 
     } 
    } 
} 
+2

你可以把所有的號碼的索引字符串中,減去隨後指數會給你時間最長的數字少串,然後就尋找那些大寫字母。你有一個循環3點,這可能永遠不會是最佳的。 – Bmo

回答

4

的Linq

  • 一個很好的問題不包含數字 - Split上數字
  • 至少一個大寫字母 - Where + Any
  • 最長(未最短)OrderByDescending
  • 最長(只有一個) - FirstOrDefault

實施

string source = .... 

var result = source 
    .Split('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') 
    .Where(line => line.Any(c => c >= 'A' && c <= 'Z')) // or char.IsUpper(c) 
    .OrderByDescending(line => line.Length) 
    .FirstOrDefault(); // null if there're no such substrings at all 
+1

相若方式,用'Regex',你可以使用'斯普利特(@ 「\ d」)''然後IsMatch( 「[A-Z]」)'。 – Scott

+1

是的,但如果不管表達簡單還是複雜,是更不用說Linq的怎麼會一個預期OP瞭解正則表達式的OP是不知道'Split'功能的..?只是想一想 – MethodMan

+1

@MethodMan:我明白了;但我認爲還有這個問題是一個很好的展示LINQ中,如何複雜的問題,可以在短短四行要解決的功率(從而鼓勵投資一些時間來研究的LINQ技術) –

1

作爲替代LINQ的答案,如果我理解正確的話,這是我會怎麼做,更換內容所有條件:

string qualifier; 
string tempQualifier; 
bool containsUpper = false; 
for (int i = 0; i < str.Length(); i++) { 
    tempQualifier += str[i]; 
    if (char.IsNumber(str[i])) { 
     if (containsUpper) { 
      if (tempQualifier.Length > qualifier.Length && tempQualifier.Length != str.Length) { 
       qualifier = tempQualifier; 
      } 

      containsUpper = false; 
     } 

     tempQualifier = ""; 
    } else if (char.IsUpper(str[i])) { 
     containsUpper = true; 
    } 
} 

return qualifier; 

這將通過字符串,建立子字符串,直到它遇到一個數字。如果子字符串包含大寫字母並且比以前的任何限定符長,則將其存儲爲新限定符(同時假定它不是所提供的字符串的長度)。道歉,如果我犯了錯誤(我不熟悉C#)。

它比LINQ的答案更長的時間,但我想那會很方便給你看的過程被分解了,所以你可以更好地理解它。

+0

謝謝!根據你的建議,我編輯了我的代碼。現在,它似乎返回沒有數字和至少一個大寫字母的最長子字符串(用戶輸入字符串)的長度。但是,如果你看到最後的結尾,我發現最長的子字符串的長度,如果我的列表是空的(即沒有找到合格的子字符串並將其放在列表中),我的程序崩潰當然,因爲'passwordList [0];'是未定義的。所以,我試圖用if語句來檢查空白,但是mayLength字符串會超出範圍(如果是的話) – Joshua