简体   繁体   English

不使用哈希图查找第一个非重复字符

[英]Find first non repeating character without using hashmap

I wanted to find first non repeating character in a string.我想在字符串中找到第一个非重复字符。 I wrote the following function in which I am stuck at one point.我写了以下函数,我一度陷入困境。 Google tells me the hashmap method for this but I'll be grateful if someone could help me with my code.谷歌告诉我这个 hashmap 方法,但如果有人能帮助我处理我的代码,我将不胜感激。

public static Character firstNonRepeatedChar(String line) {

        Character c = null;
        int strLength = line.length();

        for (int i =0; i<strLength-1; i++){

            int flag = 0;
            for(int j = i+1; j<strLength-i; j++){

                if(line.charAt(i) == line.charAt(j)){
                    flag++;
                    break;
                }
                else
                    continue;
            }

            if (flag==0){
                c = line.charAt(i);
                break;
            }


        }
        return c;
    }
}

Problem : How can I put a check that the repeating character that is already checked once is not checked again.问题:如何检查已检查过的重复字符不会再次检查。 Ex: If my string is "hhello" then the code first compares the h at index 0 with all the other characters.例如:如果我的字符串是“hhello”,那么代码首先将索引 0 处的 h 与所有其他字符进行比较。 Since its repeating the next iteration of outer for loop starts in which i now points to index 1 of the string ie the repeating h and compares it with the rest of elements.由于它重复外循环的下一次迭代,其中 i 现在指向字符串的索引 1,即重复的 h 并将其与其余元素进行比较。 Since it does not get a repeating instance it returns 'h' as non repeating character which is wrong.由于它没有得到重复实例,它返回 'h' 作为非重复字符,这是错误的。

How can I fix this?我怎样才能解决这个问题? Is there any way?有什么办法吗? Pls help请帮忙

EDIT: Repeating character need not be the immediate next character.编辑:重复字符不必是紧接的下一个字符。 Ex: In string "helloWorld" characters 'l' and 'o' are repeating.例如:在字符串“helloWorld”中,字符 'l' 和 'o' 是重复的。 In string "hehelo" characters 'h' and 'e' are repeating and first non repeating character will be 'l'在字符串“hehelo”中,字符 'h' 和 'e' 是重复的,第一个非重复字符将是 'l'

Hint 1: A repeating character 1 is one that is the same as the previous character in the String.提示1:重复字符1是与字符串中的前一个字符相同的字符。 A non-repeating character is .........非重复字符是…………

Implement that!执行那个!

Hint 2 : You don't need a nested loop.提示2:不需要嵌套循环。


UPDATE更新

I see.我知道了。 So you are using "non-repeating character" to mean something different to what most people would mean.所以你使用“非重复字符”来表示与大多数人的意思不同的东西。 What you are actually looking for is the first character that appears only once in the entire string.实际要查找的是在整个字符串中仅出现一次的第一个字符。

Anyway ... at least I now understand why you are using a nested loop now, and I understand the bug.无论如何......至少我现在明白你为什么现在使用嵌套循环,我明白这个错误。

Hint 3 : Even when a character appears multiple time in a string, it will still appear ZERO times after its last occurrence.提示 3 :即使一个字符在一个字符串中出现多次,它在最后一次出现后仍然会出现零次。

That is what your inner loop tests for.这就是您的内部循环测试的内容。 So what you are finding is the first character in the string that isn't duplicated in the remainder of the string.所以你发现的是字符串中第一个在字符串的其余部分没有重复的字符。

The fix is simple ... once you understand what you are doing wrong.修复很简单......一旦你明白你做错了什么。


Once you have fixed that are some other tidy ups:一旦你修复了其他一些整理:

  • The else continue is redundant. else continue是多余的。

  • The c variable is unnecessary ... if you change: c变量是不必要的......如果你改变:

     if (flag==0){ c = line.charAt(i); break; }

    to

     if (flag==0){ return line.charAt(i); }

    and

     return c;

    to

     return null;

1 - This is what a native English speaker understands by "find the first non-repeating character". 1 - 这就是母语为英语的人所理解的“找到第一个非重复字符”。 It is possible that you mean something else.你的意思可能是别的意思。 If so, please update the question to clarify.如果是这样,请更新问题以澄清。 Please describe as clearly as you can what you mean.请尽可能清楚地描述您的意思。 Please give examples.请举例说明。

***For all case of repetition ***对于所有重复的情况

Character c = null;
    int strLength = line.length();

    for (int i = 0; i < strLength; i++) {

        int flag = 0;
        for (int j = 0; j < strLength; j++) {
            if (line.charAt(i) == line.charAt(j) && i != j) {
                flag = 1;
                break;
            }
        }

        if (flag == 0) {
            c = line.charAt(i);
            break;
        }

    }
    return c;

This is so simple to check, Your logic is complex.这很容易检查,您的逻辑很复杂。 try this for immediate repeated character.试试这个立即重复的字符。

Character c = null;
        int strLength = line.length();

        for (int i = 0; i < strLength - 1;) {

            int flag = 0;
            int present_char_position = 0;

            if (line.charAt(i) == line.charAt(i + 1)) {
                flag++;
                present_char_position = i;
                i += 2;//jumping from those two character if matched
                continue;
            } else {
                present_char_position = i;
                i++;//if not matched go to next character
            }

            if (flag == 0) {
                c = line.charAt(present_char_position);
                break;
            }

        }
        return c;

The easiest way to flag doublets would be to replace the characters with a none printable one.标记双峰的最简单方法是用不可打印的字符替换字符。 You can then skip these positions.然后您可以跳过这些位置。 But this will add another O(n) to your loop replacing the characters.但这会在循环中添加另一个 O(n) 来替换字符。 The worst case would result in O(n^3).最坏的情况将导致 O(n^3)。 Optimizing you could write an inner loop replacing only the characters ahead of your current position.优化您可以编写一个内部循环,仅替换当前位置之前的字符。 This would result in a O(n^2) again, because currently you have O(n^2) (n*n/2).这将再次导致 O(n^2),因为目前您有 O(n^2) (n*n/2)。

UPDATE Added code and fixed a bug, where the non repeating character is at last position of the String .更新添加了代码并修复了一个错误,其中非重复字符位于String最后位置。 Instead of processing the String , now processing the char[] .现在处理char[]而不是处理String

private static final char FLAG = '\u0000';

public static Character firstNonRepeatedChar(String line)
{
    final char[] chars = line.toCharArray();
    Character c = null;

    final int strLength = chars.length;

    for (int i = 0; i < strLength; i++)
    {
        if (chars[i] == FLAG)
        {
            continue;
        }

        int flag = 0;
        for (int j = i + 1; j < strLength; j++)
        {
            if (chars[i] == chars[j])
            {
                flag++;
                chars[j] = FLAG;
            }
        }

        if (flag == 0)
        {
            c = chars[i];
            break;
        }
    }
    return c;
}

Below method will return you what you are looking.下面的方法将返回您正在查找的内容。

public static char getFirstNonRepeatedChar(String input) {        
    char c = 0;
    for (int i =0; i<input.length(); i++){
        int flag = 0;
        for(int j = 0; j<input.length(); j++){
            if(input.charAt(i) == input.charAt(j)){
                flag++;
            }
            if(flag>1)
                break;
        }
        if (flag == 1){
            c = input.charAt(i);
            break;
        }
    }
    return c;
}

This one is for PHP这是用于 PHP 的

<?php

$string = "ABBGAACCE";

$stringArray = str_split($string); // string converted to array
$temp_array = [];
$non_repeating_array = get_first_non_repeating($stringArray, $temp_array);

echo reset($non_repeating_array); // display first non repeating character from string

function get_first_non_repeating($stringArray, $temp_array)
{
    $repeating = []; // store all repeating characters
    foreach($stringArray as $key => $char)
    {
        if(array_key_exists($char, $temp_array)) // check if character was already saved meaning it is repeating
        {
            array_push($repeating, $char); // push all repeating character in a variable
            $stringArray = array_diff($stringArray, $repeating); // subtract repeating characters from the string array
        }else{
            $temp_array[$char] = 1;
        }
    }
    return $stringArray; // returns the non repeating characters
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM