使用java在字符串及其位置中打印第一个重复字符

时间:2015-02-07 15:33:08

标签: java string loops operations

可以请优化下面的代码..

要求:打印字符串中的第一个重复字符及其位置。 示例: 案例1:字符串值为" XYABXB" 输出应该是:First Repeat Character是:X在位置:1,重复字符在位置:5 案例2:字符串值是" AABCDEB" 输出应该是:首先重复字符是:A位置:1,重复字符位于:2 案例3:字符串值是" ABCDFG" Out Put应该是:'没有找到重复的字符'

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");
    }
}

4 个答案:

答案 0 :(得分:2)

只需将Map<Character, Integer>与char一起使用并在数组中定位,然后继续添加。调用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");

答案 1 :(得分:1)

这是一个仅使用原始java特性的解决方案,它使用布尔数组来标记字符&#34; hit&#34;。它依赖于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");
}

想法是迭代字符串,每次我们看到一个字符时,检查我们是否已经看过它。如果我们这样做,我们立即打印并返回。如果我们没有 - 我们已将其标记为已经&#34;点击&#34;并继续。

代码演练(printRepeats):

第1部分 - 数组分配:

存储我们的&#34;点击&#34;我们需要一个可以查找过去字符的数据结构。第一个语句创建一个我们需要的数组。由于大写字母在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非常有用,所以我们可以依赖它。
  3. 循环代码:

        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");
    }
    

    可以通过将第一个出现的索引与它的旁边一起存储来进一步优化打印部分&#34;看到/看不到&#34;状态使用一些巧妙的映射到原始对象而不是使用String.indexOf,但它会降低代码的可读性。

    提示:我不打扰记忆特定的ASCII表(也不应该有人)。我只记住ASCII表的顺序(这种情况 - 大写英文字母是连续的)。

    奖金 - 简​​短,浪费,版本:

    较短的版本可以按如下方式组成:

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

    代码:

    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的方法,因此它的含量更高。

答案 2 :(得分:0)

简单易用的解决方案

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";
    }
}

答案 3 :(得分:0)

简短而简单>

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