Go逐行处理文件及k-string筛选函数无输出问题排查
Hey there! Let's break down the issues in your code and fix them step by step to get your findMajorDifference function working as expected.
Key Issues in Your Current Code
Incorrect File Processing
You’re passing the entire byte content ofwords.txtdirectly to your function, treating the whole file as a single string. Butwords.txtis almost certainly a list of words (one per line)—you need to split the file into individual words first.Flawed Minimum Distance Calculation
- The
minvariable is initialized once at the start of the function, but it should reset for every word (otherwise, leftover values from previous words will break your logic). - You’re calculating linear distance instead of circular distance (the alphabet is a ring). For example, the distance between 'a' and 'z' should be 1, not 25—you need to take the minimum of the linear distance and
26 - linear distance. - Your nested loops repeat redundant comparisons (e.g., checking index 0 vs 1, then index 1 vs 0 again) and waste resources.
- The
Wrong k-string Matching Logic
A word is ak-stringif all pairs of distinct letters have a circular distance greater than k. So if a word’s minimum circular distance isd, it qualifies as ak-stringfor allk < d. To get 10-string, 11-string, and 12-string words, we need words whered > 10,d > 11, ord > 12(i.e., minimum distance ≥11, ≥12, ≥13 respectively). Your current condition checks for exact matches of 11/12/13 and collects single characters instead of full words.Incorrect Result Collection
You’re appendingstring(B[i])(individual characters) to your result slice instead of the full qualifying word.
Fixed Code Implementation
package main import ( "bufio" "fmt" "os" "unicode" ) // findMajorDifference takes a list of words and returns all words that are 10-string, 11-string, or 12-string func findMajorDifference(words []string) []string { major := []string{} alpha := "abcdefghijklmnopqrstuvwxyz" // Create a map for quick letter-to-position lookup (avoids repeated loops through the alphabet) posMap := make(map[rune]int) for idx, c := range alpha { posMap[c] = idx } for _, word := range words { // Collect unique characters in the word (no need to compare duplicates) uniqueChars := make(map[rune]bool) for _, c := range word { uniqueChars[unicode.ToLower(c)] = true // handle uppercase letters if present } // Convert unique chars to a slice for easy pairing chars := make([]rune, 0, len(uniqueChars)) for c := range uniqueChars { chars = append(chars, c) } if len(chars) < 2 { // Words with fewer than 2 distinct characters can't qualify (no pairs to check) continue } minDistance := 26 // Initialize to max possible distance (26 letters) // Compare all unique character pairs exactly once for i := 0; i < len(chars); i++ { for j := i + 1; j < len(chars); j++ { pos1 := posMap[chars[i]] pos2 := posMap[chars[j]] // Calculate circular distance (alphabet is a ring) linearDist := abs(pos1 - pos2) circularDist := min(linearDist, 26-linearDist) if circularDist < minDistance { minDistance = circularDist } } } // Check if the word qualifies as 10-string, 11-string, or 12-string // A word with minDistance >12 is automatically a 11 and 10-string too if minDistance > 10 { major = append(major, word) } } return major } // Helper function for absolute value func abs(x int) int { if x < 0 { return -x } return x } // Helper function for minimum of two integers func min(a, b int) int { if a < b { return a } return b } func main() { // Open the words file file, err := os.Open("words.txt") if err != nil { fmt.Println("File reading error:", err) return } defer file.Close() // Read the file line by line to get individual words var words []string scanner := bufio.NewScanner(file) for scanner.Scan() { word := scanner.Text() if word != "" { // skip empty lines words = append(words, word) } } if err := scanner.Err(); err != nil { fmt.Println("Error scanning file:", err) return } // Get and print qualifying words result := findMajorDifference(words) fmt.Println("Qualified words (10-string, 11-string, 12-string):") for _, word := range result { fmt.Println(word) } }
What Changed & Why
Proper File Line Reading
We usebufio.Scannerto read the file line by line, splitting content into individual words—this fixes the core issue of treating the entire file as one string.Optimized Character Lookup
AposMapis created once to map each letter to its alphabet position, eliminating repeated loops through thealphastring.Unique Character Handling
We collect only unique characters per word to avoid redundant comparisons (no need to compare a character to itself or the same pair twice).Correct Circular Distance Calculation
For each character pair, we compute the circular distance by taking the minimum of the linear distance and26 - linear distance, which aligns with the "alphabet ring" requirement.Fixed k-string Logic
We check if the minimum circular distance is greater than 10—this captures all words that are 10-string, 11-string, or 12-string (since a 12-string is automatically a 11 and 10-string).Result Collection
We append full qualifying words to the result slice instead of individual characters.
内容的提问来源于stack exchange,提问作者N Amilah

