如何重构仅使用循环和简单数组的代码?

Posted

技术标签:

【中文标题】如何重构仅使用循环和简单数组的代码?【英文标题】:How to refacor a code use only loops and simple arrays? 【发布时间】:2018-07-10 15:10:42 【问题描述】:

我编写了该代码并且它正在工作。但我需要重构它。我只能使用简单的方法来解决问题,例如:“for”循环和简单数组。

public class Anagram 

public static void main(String[] args) throws IOException 

    Anagram anagrama = new Anagram();

   try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));) 

        System.out.println("Enter word or phrase: ");
        String userText = reader.readLine();
        String resultAnagrama = anagrama.makeAnagram(userText);
        System.out.println("Result of Anagrama : " + resultAnagrama);                   
         

此方法获取用户的文本并制作字谜,但所有非字母应保持在同一位置

/**
 * @param text
 * @return reversed text and all non-letter symbols stay on the same places
 */
public String makeAnagram(String text) 

    HashMap<Integer, Character> mapNonLetters;

    String[] textFragments = text.split(" ");
    StringBuilder stringBuilder = new StringBuilder();

    //Check each elements of array for availability symbols and make reverse of elements
    for (int i = 0; i < textFragments.length; i++) 
        char[] arrayCharacters = textFragments[i].toCharArray();
        mapNonLetters = saerchNonLetters(arrayCharacters); // search symbols

        StringBuilder builderAnagramString = new StringBuilder(textFragments[i]);

        //Delete all non-letters from element of array
        int reindexing = 0;
        for (HashMap.Entry<Integer, Character> entry : mapNonLetters.entrySet()) 
            int key = entry.getKey();
            builderAnagramString.deleteCharAt(key - reindexing);
            reindexing ++;
        

        builderAnagramString.reverse();

        //Insert all non-letters in the same places where ones stood
        for (HashMap.Entry<Integer, Character> entry : mapNonLetters.entrySet()) 
            int key = entry.getKey();
            char value = entry.getValue();
            builderAnagramString.insert(key, value);
        

        textFragments[i] = builderAnagramString.toString(); 
        stringBuilder.append(textFragments[i]); 

        if (i != (textFragments.length - 1)) 
            stringBuilder.append(" ");
        
        mapNonLetters.clear();
    
    return stringBuilder.toString();

此方法从用户文本的每个字中搜索所有非字母

/**
 * Method search symbols
 * @param arrayCharacters
 * @return HashMap with symbols found from elements of array
 */
public HashMap<Integer, Character> saerchNonLetters(char[] arrayCharacters) 

    HashMap<Integer, Character> mapFoundNonLetters = new HashMap<Integer, Character>();

        for (int j = 0; j < arrayCharacters.length; j++) 
            //Letters lay in scope 65-90 (A-Z) and 97-122 (a-z) therefore other value is non-letter
            if (arrayCharacters[j] < 65 || (arrayCharacters[j] > 90 && arrayCharacters[j] < 97) ||
                    arrayCharacters[j] > 122) 
                mapFoundNonLetters.put(j, arrayCharacters[j]);
            
        
        return mapFoundNonLetters;
    

【问题讨论】:

你尝试了什么?你的代码有什么问题? 见How to create a Minimal, Complete, and Verifiable example 你只需要 1 个字谜? 此代码工作正常,但我需要在没有 HashMap 的情况下覆盖此代码 【参考方案1】:
public class Anagram 
public static void main(String[] args) 
    String text = "!Hello123 ";
    char[] chars = text.toCharArray();

    int left = 0;
    int right = text.length() - 1;

    while (left < right) 
        boolean isLeftLetter = Character.isLetter(chars[left]);
        boolean isRightLetter = Character.isLetter(chars[right]);
        if (isLeftLetter && isRightLetter) 
            swap(chars, left, right);
            left++;
            right--;
         else 
            if (!isLeftLetter) 
                left++;
            

            if (!isRightLetter) 
                right--;
            
        
    

    String anagram = new String(chars);
    System.out.println(anagram);


private static void swap(char[] chars, int index1, int index2) 
    char c = chars[index1];
    chars[index1] = chars[index2];
    chars[index2] = c;

【讨论】:

【参考方案2】:

如果我理解正确并且您只需要 1 个字谜,这应该可以:

String originalString = "This is 1 sentence with 2 numbers!";
System.out.println("original: "+originalString);

// make a mask to keep track of where the non letters are
char[] mask = originalString.toCharArray();
for(int i=0; i<mask.length; i++)
  mask[i] = Character.isLetter(mask[i]) ? '.' : mask[i];
System.out.println("mask:     "+ new String(mask));

// remove non letters from the string
StringBuilder sb = new StringBuilder();
for(int i=0; i< originalString.length(); i++) 
  if(mask[i] == '.')
    sb.append(originalString.charAt(i));


// find an anagram
String lettersOnlyAnagram = sb.reverse().toString();

// reinsert the non letters at their place
int letterIndex = 0;
for(int i=0; i<mask.length; i++) 
  if(mask[i] == '.') 
    mask[i] = lettersOnlyAnagram.charAt(letterIndex);
    letterIndex++;
  


String anagram = new String(mask);
System.out.println("anagram:  "+ anagram);

打印出来:

original: This is 1 sentence with 2 numbers!
mask:     .... .. 1 ........ .... 2 .......!
anagram:  sreb mu 1 nhtiwecn etne 2 ssisihT!

【讨论】:

以上是关于如何重构仅使用循环和简单数组的代码?的主要内容,如果未能解决你的问题,请参考以下文章

如何优化此代码以仅显示圆形数组的轮廓?

重构嵌套循环后的段错误

如何在 foreach 循环代码中重构此变量分配?

如何停止循环以仅获取第一个数组的内容?

清晰代码和代码重构大纲

SwiftUI:如何使用 ForEach 循环使用各种代码的各种结构?