【问题标题】:Print First Repeat Character in a string and it's positions using java使用java打印字符串中的第一个重复字符及其位置
【发布时间】:2015-02-07 15:33:07
【问题描述】:

请优化下面的代码..

要求:打印字符串中的第一个重复字符及其位置。 例子 : 案例1:字符串值为“XYABXB” 输出应该是:第一个重复字符是:X 在位置:1,重复字符在位置:5 案例 2:字符串值为“AABCDEB” 输出应该是:第一个重复字符是:A 在位置:1,重复字符在位置:2 案例 3:字符串值为“ABCDFG” 输出应为:'未找到重复字符'

public void printFirstOccuranceOfRepeatCharactor(String inputString){
    char [] words = inputString.toCharArray();
    boolean repeatCharFound = false;
    for (int i = 0; i < words.length; i++) {
        if(!repeatCharFound){
            char charPos = words[i];
            for (int j = i+1; j < words.length; j++) {
                if(charPos == words[j]){
                    System.out.println("First Repeating Char is : "+words[j] + " and First Occurrance is at :" + (i+1) +" And repeat char At position :" + (j+1));
                    repeatCharFound = true;
                    break;
                }
            }
        }
    }
    if(!repeatCharFound){
        System.out.println("No repeat charector found");
    }
}

【问题讨论】:

  • 第一个重复字符是:A 在位置:1,重复字符在位置:4
  • 不抱怨.. 我只是说你可以通过循环来实现这一点,你不需要在这里有一个正则表达式。而且我不是反对者..

标签: java string loops operations


【解决方案1】:

只需将Map&lt;Character, Integer&gt; 与数组中的字符和位置一起使用,然后继续添加。调用 Map 的 get 方法,如果它返回位置,那么这就是你要返回的。

Map<Character, Integer> map = new HashMap<Character, Integer>();
Integer number;
for (int i =0; i<words.length; i++) {
    number = map.get(words[i]);
    if (number != null) {
        return number;//that's the position
    } else {
        map.put(words[i], i)
    }
}
System.out.println("No repeat charector found");

【讨论】:

    【解决方案2】:

    这是一个仅使用原始 Java 功能的解决方案,它使用布尔数组来标记已经“命中”的字符。它依赖于ASCII Table顺序,以及只有大写字符的字符串:

    private static void printRepeats(String test) {
        // "only upper-case characters" requires options 'A' to 'Z'.
        // this is asciiValue('Z') - asciiValue('A') (implicitly done by Java) + 1
        boolean[] charHits = new boolean['Z' - 'A' + 1];
    
        for (int i=0; i < test.length(); i++){
            // our current character
            char current = test.charAt(i);
            if (charHits[current - 'A']){
                // character index already set in charHits array - already seen!
                // print and return
                System.out.println(
                    current + " is repeated, first occurrence "
                    + test.indexOf(current) + ", second: " + i
                );
                return;
            } else {
                // first hit - mark as already occurred for future iterations
                charHits[current - 'A'] = true;
            }
        }
        // no character repeats found
        System.out.println("No repeats");
    }
    

    这个想法是迭代字符串,每次我们看到一个字符,检查我们是否已经看到它。如果我们这样做了,我们会立即打印并返回。如果我们没有 - 我们将其标记为已经“命中”并继续。

    代码演练 (printRepeats):

    第 1 部分 - 数组分配:

    为了存储我们的“命中”,我们需要一个可以查找过去字符的数据结构。第一条语句创建了一个我们需要的大小的数组。由于大写字母在 ASCII 表中是连续的(A - 65 到 Z - 90),我们知道我们只需要一个 [90 - 65 + 1 = 26] 大小的数组来容纳所有大写字母。每个字符命中都映射到数组中的索引[the characters ASCII value] - [A's ASCII value]。所以:

    LETTER -> INDEX IN ARRAY
    'A' -> 0
    'B' -> 1
    ...
    'Z' -> 25
    

    所以要分配这样的数组,我们使用:

    boolean[] charHits = new boolean['Z' - 'A' + 1];
    

    正是像:

    new boolean[26];
    

    您可以通过以下方式检查:

    System.out.println('Z' - 'A' + 1); // 26
    

    甚至:

    System.out.println(new boolean['Z' - 'A' + 1].length); // 26
    

    第 2 部分 - 字符串迭代:

    这部分迭代给定的String,有两个选项:

    1. 将字符标记为seen
    2. 发现重复,打印并返回

      • 知道布尔数组会自动初始化为 false 很有用,因此我们可以依赖它。

    循环代码:

        for (int i=0; i < test.length(); i++){
            // our current character
            char current = test.charAt(i);
            if (charHits[current - 'A']){
                // character index already set in charHits array - already seen!
                // print and return
                System.out.println(
                    current + " is repeated, first occurrence "
                    + test.indexOf(current) + ",  second repeat: " + i
                );
                return;
            } else {
                // first hit - mark as already occurred for future iterations
                charHits[current - 'A'] = true;
            }
        }
        // no character repeats found - no index in array hit twice
        System.out.println("No repeats");
    }
    

    打印部分可以通过使用一些巧妙的映射到原始对象而不是使用String.indexOf,将第一次出现的索引与其“已看到/未看到”状态一起存储,从而进一步优化,但它会降低代码的可读性。

    提示:我不会费心记住特定的 ASCII 表 (任何人也不应该)。我只记住 ASCII 表的 order(这种情况 - 大写英文字母是连续的)。

    奖金 - 一个简短而浪费的版本:

    一个较短的版本可以组成如下:

    对于每个可能的前缀(短到长),检查前缀后面的第一个字符是否在前缀中。如果是,那就是第一次重复。

    代码:

    public static void printRepeatsShort(String test){
        for (int i=0; i< test.length(); i++){
            // check index of following character in prefix
            int indexInPrefix = test.substring(0, i).indexOf(test.charAt(i));
            if ((indexInPrefix != -1){
                // next character is in prefix, return
                System.out.println(
                    "Repeated char: '" + test.charAt(i) + "', First: "
                    + indexInPrefix + " Second: " + i
                );
                return;
            }
        }
        System.out.println("No repeats found");
    }
    

    这个版本远没有那么理想,但只依赖于来自String 的方法,所以它包含更多内容。

    【讨论】:

      【解决方案3】:

      简单易行的解决方案

      import java.util.Scanner;
      
      public class firstrepchar {
      
          static Scanner sn = new Scanner(System.in);
          static String word = sn.nextLine();
      
          public static void main(String[] args) {
              System.out.println("The Result is " + check(word));
          }
      
          private static String check(String word) {
              String store = "";
              for (int i = 0; i < word.length(); i++) {
                  if (store.indexOf(word.charAt(i)) < 0) {
                      store = store + word.charAt(i);
                  } else {
                      return word.charAt(i) + " at position " + i;
                  }
              }
              System.out.println("Result word " + store);
              return "nothing found";
          }
      }
      

      【讨论】:

        【解决方案4】:

        简短而简单>

        void findFirstDupChar() {
                String s = "google";
                Integer dupIndex = s.length() - 1;
                boolean isDuplicateExists = false;
                Map<Character, Integer> map = new LinkedHashMap<>();
        
                char[] words = s.toCharArray();
                for (int i = 0; i < words.length; i++) {
                    Integer index = map.put(words[i], i);
                    if (index != null) {
                        if (index < dupIndex) {
                            dupIndex = index;
                            isDuplicateExists = true;
                        }
                    }
                }
                System.out.println(isDuplicateExists ? words[dupIndex] + ", index=" + dupIndex : "No duplicateds found");
            }
        

        这将打印输出如下 >
        g, 索引=0

        【讨论】:

          猜你喜欢
          • 2019-02-19
          • 1970-01-01
          • 2021-10-15
          • 1970-01-01
          • 2014-08-01
          • 1970-01-01
          • 2019-03-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多