Using java, input string="aabbcdeaaaabbb" and the output must be aaaa - java

Using java, input string="aabbcdeaaaabbb" and the output must be aaaa, as sequence here is having repeated 4 times a. Can anyone help me to get this "aaaa" as output using java implementation.
Algorithm to find the Longest substring having same character repeated.
for eg:
I/P: aabbcdefaaaacccccc O/P: cccccc
Please check my program below and suggest any optimization for faster processing:
public class LongestSubString {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
System.out
.println("Enter a word to find longest substring with same characters repeated");
String word = reader.readLine();
System.out.println("Entered word is: " + word);
System.out.println("Longest repeated characters substring is: "
+ subStringFinder(word));
}
/*
*longest substring finder with same character repeated
*/
public static String subStringFinder(String word) {
char[] tokens = word.toCharArray();
int len = tokens.length;
int wordLen = word.length();
System.out.println("len of input word: " + wordLen);
List<String> myList = new ArrayList<>();
StringBuilder strConcat = new StringBuilder("");
for (int j = 0; j <= len - 1; j++) {
if (j + 1 > len - 1) {
if ((strConcat.length() >= 1)
&& (strConcat.charAt(strConcat.length() - 1) == (tokens[j]))) {
strConcat.append("" + tokens[j]);
myList.add(strConcat.toString());
}
}
else {
if (tokens[j] == tokens[j + 1]) {
if ((strConcat.length() >= 1)
&& (strConcat.charAt(strConcat.length() - 1) == (tokens[j]))) {
strConcat.append("" + tokens[j]);
myList.add(strConcat.toString());
} else {
strConcat = new StringBuilder("");
strConcat.append("" + tokens[j]);
}
} else {
if ((strConcat.length() >= 1)
&& (strConcat.charAt(strConcat.length() - 1) == (tokens[j]))) {
strConcat.append("" + tokens[j]);
myList.add(strConcat.toString());
} else {
strConcat = new StringBuilder("");
strConcat.append("" + tokens[j]);
}
}
}
}
int max = 0, index = 0;
for (int i = 0; i < myList.size(); i++) {
String strEle = myList.get(i);
int strLen = strEle.length();
if (max < strLen) {
max = strLen;
index = i;
}
}
return myList.get(index);
}
}

I believe your code is overly complicated. You don’t need a StringBuilder nor an ArrayList. I tried to understand your intention, but then skipped it and wrote my own version instead. Hope it helps anyway.
public static String subStringFinder(String word) {
if (word == null || word.isEmpty()) {
return word;
}
char currentChar = word.charAt(0);
int longestStart = 0;
int longestLength = 0;
int currentStart = 0;
int currentLength = 1;
for (int ix = 1; ix < word.length(); ix++) {
if (word.charAt(ix) == currentChar) {
currentLength++;
} else {
if (currentLength > longestLength) {
longestStart = currentStart;
longestLength = currentLength;
}
currentChar = word.charAt(ix);
currentStart = ix;
currentLength = 1;
}
}
if (currentLength > longestLength) {
longestStart = currentStart;
longestLength = currentLength;
}
return word.substring(longestStart, longestStart + longestLength);
}

String in = "aabbcdeaaaabbb";
String t;
ArrayList<String> out = new ArrayList<String>();
String l="";
int c=0;
String n;
for(int i=0;i<in.length;i++) {
n=in.substring(i, i+1); //get the current character
if(n.equals(l)){
l=n; c++;
}
else {
t=n;
for(int j=1;j<c;j++) {
n+=t;
}
c=0;
out.add(n);
c=0;
}
}

Related

Array index out of bounds exception. Please help if you can [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 5 years ago.
Extremely close to having this task finished but can't see which part of this is holding me back. If anybody could put me on the right track I'd be very thankful. the following is the error code that eclipse gives me each time I try to run this.
**Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2
at lab01.EncodeDecode.backMap(EncodeDecode.java:162)
at lab01.EncodeDecode.Decode(EncodeDecode.java:68)
at lab01.EncodeDecode.(EncodeDecode.java:26)
at lab01.EncodeDecodeTester.main(EncodeDecodeTester.java:14)**
package lab01;
import java.util.*;
/**
*
* #author David Bierbrauer,
*
*/
public class EncodeDecode
{
//method declaration
static String[] originalList,encodedList,decodedList;
static int total;
public EncodeDecode(String[] oL)
{
//instance variable declaration
total = oL.length;
originalList = new String[total];
encodedList = new String[total];
decodedList = new String[total];
originalList = oL;
encodedList= Encode(originalList);
decodedList = Decode(encodedList);
}
public static String[] Encode (String[] originalList)
{
//declare control variables
String currentWord = "", codedWord = "";
char currentChar = ' ';
int i = 0, j = 0, stringLength = 0;
for (i=0; i < total ; i++)
{
currentWord = originalList[i];
stringLength = currentWord.length();
for (j = 0; j < stringLength; j++)
{
currentChar = currentWord.charAt(j);
codedWord = codedWord +forwardMap(currentChar);
}
encodedList[i] = codedWord;
codedWord = "";
}
return encodedList;
}
public static String[] Decode (String[] encodedList)
{
String currentWord = "", encodedWord = "";
char currentChar = ' ';
int i =0, j=0, stringLength = 0;
for(i = 0; i < total; i++)
{
currentWord = encodedList[i];
stringLength = currentWord.length();
for(j = 0; j < stringLength; j++)
{
currentChar = currentWord.charAt(j);
encodedWord = encodedWord + backMap(currentChar);
}
decodedList[i] = encodedWord;
encodedWord = "";
}
return decodedList;
}
public static char forwardMap(char currentChar)
{
char newChar = ' ';
int i = 0;
String encodeMapUpper = "CDEFGHIJKLMNOPQRSTUVWXYZAB";
String encodeMapLower = "cdefghijklmnopqrstuvwxyzab";
String encodeMapNumber = "2345678901";
char [] encodeArrayUpper = encodeMapUpper.toCharArray();
char [] encodeArrayLower = encodeMapLower.toCharArray();
char [] encodeArrayNumber = encodeMapNumber.toCharArray();
if(encodeMapUpper.indexOf(currentChar) != -1)
{
for( i = 0; i < encodeArrayUpper.length; i++)
{
if(currentChar == encodeArrayUpper[i])
{
newChar = encodeArrayUpper[(i+2) % 26];
}
}
}
else if(encodeMapLower.indexOf(currentChar) != -1)
{
for( i = 0; i < encodeArrayLower.length; i++)
{
if(currentChar == encodeArrayLower[i])
{
newChar = encodeArrayLower[(i+2) % 26];
}
}
}
else if(encodeMapNumber.indexOf(currentChar) != -1)
{
for( i = 0; i < encodeArrayNumber.length; i++)
{
if(currentChar == encodeArrayNumber[i])
{
newChar = encodeArrayNumber[(i+2) % 10];
}
}
}
else
{
//element is a special character
newChar = currentChar;
}
return newChar;
}
public static char backMap(char currentChar)
{
char newChar = ' ';
int i = 0;
String decodeMapUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String decodeMapLower = "abcdefghijklmnopqrstuvwxyz";
String decodeMapNumber = "0123456789";
char[] decodeArrayUpper = decodeMapUpper.toCharArray();
char[] decodeArrayLower = decodeMapLower.toCharArray();
char[] decodeArrayNumber = decodeMapNumber.toCharArray();
if (decodeMapUpper.indexOf(currentChar) != -1)
{
for (i=0; i < decodeArrayUpper.length; i++)
{
if (currentChar == decodeArrayUpper[i])
{
newChar = decodeArrayUpper[(i - 2) % 26];
}
}
}
else if(decodeMapLower.indexOf(currentChar) != -1)
{
for (i=0; i < decodeArrayLower.length; i++)
{
if (currentChar == decodeArrayLower[i])
{
newChar = decodeArrayLower[(i - 2) % 26];
}
}
}
else if(decodeMapNumber.indexOf(currentChar) != -1)
{
for (i=0; i < decodeArrayNumber.length; i++)
{
if (currentChar == decodeArrayNumber[i])
{
newChar = decodeArrayNumber[(i - 2) % 10];
}
}
}
else
{
newChar = currentChar;
}
return newChar;
}
//get methods
public String[] getEncodedList() { return encodedList;}
public String[] getDecodedList() { return decodedList;}
}
This is the tester class bellow just in case.
package lab01;
public class EncodeDecodeTester
{
public static void main(String[] args)
{
EncodeDecode testEncoder;
int x = 0;
String[] output = new String[5];
String[] oL = new String[] {"catdog","24","keys","Duck","PIZZA!"};
//create encoder
testEncoder = new EncodeDecode(oL);
System.out.println("Encoded list:");
for( x = 0; x < output.length; x++)
{
output = testEncoder.getEncodedList();
System.out.println(output[x]);
}
System.out.println();
System.out.println("Decoded List:");
for(x = 0; x < output.length; x++)
{
output = testEncoder.getDecodedList();
System.out.println(output[x] + " ");
}
System.out.println();
System.out.println("End");
}
}
Please help I am completely lost for words on what I did wrong here.
The Java % operator doesn't always produce a number between 0 and the second operand. Replace (i - 2) % 26 (which can produce -2) with (i + 24) % 26 and similarly in other places.

Extract the particular portion from a String

I have the below String variable
String s = "abc,xyz,lmn,ijk";
I want to extract only the portion of the String (i.e - 'lmn')
And, Should not use in-built functions like, SubString(), Split(), IndexOf(). But I can use charArray()
And this question was asked in my interview.
I tried the below code,
But not sure how to proceed. Can any one please provide your thoughts?
String s = "abc,xyz,lmn,ijk";
int counter = 0;
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
if (ch[i] == ',') {
counter++;
}
}
Here's one way:
public static void main(String[] args) {
String s = "abc,xyz,lmn,ijk";
char[] ch = s.toCharArray();
int counter = 0;
int place = 2;
for (int i = 0; i < ch.length-2; i++) {
if(ch[i] == ',') {
counter++;
}
if(counter == place && ch[i] != ',') {
System.out.print(ch[i]);
}
}
}
It prints everything after the second comma, but before the third one.
public static void main(String[] args) {
// TODO Auto-generated method stub
String s = "abc,xyz,lmn,ijk";
StringBuffer sb=new StringBuffer();
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
if(','==(ch[i]))
{
if (sb.toString().equals("lmn")) {
System.out.println(sb.toString());
}
else
{
int length=sb.length();
sb.delete(0, length);
}
}
else
{
sb.append(ch[i]);
}
}
}
I would do it this way.
String s = "abc,xyz,lmn,ijk";
String x = "c,x"; // String to found
String r = "";
boolean coincidence = false;
int a=0; // Initial index if of the first character in x is found
int b=0; // Last index If it was possible to search for the last character of x
int c=0; // Index "iterator" on String x
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
if(c == x.length())
break;
else{
if(ch[i] == x.charAt(c) && !coincidence){
a = i; b = i; c++;
coincidence = true;
}
else if(ch[i] == x.charAt(c) && coincidence){
b++; c++;
}else{
coincidence = false;
a = 0; b = 0; c = 0;
}
}
}
System.out.println("String: " + s);
System.out.println("String to find: " + x);
System.out.println("Was found? " + ((coincidence)? "Yes" : "No"));
if(coincidence){
System.out.println("Intervals indexes in String: ["+a + "," + b +"]");
// String extration
for (int i = a; i <= b; i++)
r += s.charAt(i);
System.out.println("String extracted: " + r);
}

Find the first non repeating character in a string

I m writing a method to find the first non repeating character in a string. I saw this method in a previous stackoverflow question
public static char findFirstNonRepChar(String input){
char currentChar = '\0';
int len = input.length();
for(int i=0;i<len;i++){
currentChar = input.charAt(i);
if((i!=0) && (currentChar!=input.charAt(i-1)) && (i==input.lastIndexOf(currentChar))){
return currentChar;
}
}
return currentChar;
}
I came up with a solution using a hashtable where I have two for loops (not nested) where I interate through the string in one loop writing down each occurance of a letter (for example in apple, a would have 1, p would have 2, etc.) then in the second loop I interate through the hashtable to see which one has a count of 1 first. What is the benefit to the above method over what I came up with? I am new to Java does having two loops (not nested) hinder time complexity. Both these algorithms should have O(n) right? Is there another faster, less space complexity algorithm for this question than these two solutions?
public class FirstNonRepeatCharFromString {
public static void main(String[] args) {
String s = "java";
for(Character ch:s.toCharArray()) {
if(s.indexOf(ch) == s.lastIndexOf(ch)) {
System.out.println("First non repeat character = " + ch);
break;
}
}
}
}
As you asked if your code is from O(n) or not, I think it's not, because in the for loop, you are calling lastIndexOf and it's worst case is O(n). So it is from O(n^2).
About your second question: having two loops which are not nested, also makes it from O(n).
If assuming non unicode characters in your input String, and Uppercase or Lowercase characters are assumed to be different, the following would do it with o(n) and supports all ASCII codes from 0 to 255:
public static Character getFirstNotRepeatedChar(String input) {
byte[] flags = new byte[256]; //all is initialized by 0
for (int i = 0; i < input.length(); i++) { // O(n)
flags[(int)input.charAt(i)]++ ;
}
for (int i = 0; i < input.length(); i++) { // O(n)
if(flags[(int)input.charAt(i)] > 0)
return input.charAt(i);
}
return null;
}
Thanks to Konstantinos Chalkias hint about the overflow, if your input string has more than 127 occurrence of a certain character, you can change the type of flags array from byte[] to int[] or long[] to prevent the overflow of byte type.
Hope it would be helpful.
The algorithm you showed is slow: it looks for each character in the string, it basically means that for each character you spend your time checking the string twice!! Huge time loss.
The best naive O(n) solution basically holds all the characters in order of insertion (so the first can be found) and maps a mutable integer to them. When we're done, analyzing, we go through all the entries and return the first character that was registered and has a count of 1.
There are no restrictions on the characters you can use. And AtomicInteger is available with import java.util.concurrent.atomic.AtomicInteger.
Using Java 8:
public static char findFirstNonRepChar(String string) {
Map<Integer,Long> characters = string.chars().boxed()
.collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()));
return (char)(int)characters.entrySet().stream()
.filter(e -> e.getValue() == 1L)
.findFirst()
.map(Map.Entry::getKey)
.orElseThrow(() -> new RuntimeException("No unrepeated character"));
}
Non Java 8 equivalent:
public static char findFirstNonRepChar(String string) {
Map<Character, AtomicInteger> characters = new LinkedHashMap<>(); // preserves order of insertion.
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
AtomicInteger n = characters.get(c);
if (n == null) {
n = new AtomicInteger(0);
characters.put(c, n);
}
n.incrementAndGet();
}
for (Map.Entry<Character, AtomicInteger> entry: characters.entries()) {
if (entry.getValue().get() == 1) {
return entry.getKey();
}
}
throw new RuntimeException("No unrepeated character");
}
import java.util.LinkedHashMap;
import java.util.Map;
public class getFirstNonRep {
public static char get(String s) throws Exception {
if (s.length() == 0) {
System.out.println("Fail");
System.exit(0);
} else {
Map<Character, Integer> m = new LinkedHashMap<Character, Integer>();
for (int i = 0; i < s.length(); i++) {
if (m.containsKey(s.charAt(i))) {
m.put(s.charAt(i), m.get(s.charAt(i)) + 1);
} else {
m.put(s.charAt(i), 1);
}
}
for (Map.Entry<Character, Integer> hm : m.entrySet()) {
if (hm.getValue() == 1) {
return hm.getKey();
}
}
}
return 0;
}
public static void main(String[] args) throws Exception {
System.out.print(get("Youssef Zaky"));
}
}
This solution takes less space and less time, since we iterate the string only one time.
Works for any type of characters.
String charHolder; // Holds
String testString = "8uiuiti080t8xt8t";
char testChar = ' ';
int count = 0;
for (int i=0; i <= testString.length()-1; i++) {
testChar = testString.charAt(i);
for (int j=0; j < testString.length()-1; j++) {
if (testChar == testString.charAt(j)) {
count++;
}
}
if (count == 1) { break; };
count = 0;
}
System.out.println("The first not repeating character is " + testChar);
I accumulated all possible methods with string length 25'500 symbols:
private static String getFirstUniqueChar(String line) {
String result1 = null, result2 = null, result3 = null, result4 = null, result5 = null;
int length = line.length();
long start = System.currentTimeMillis();
Map<Character, Integer> chars = new LinkedHashMap<Character, Integer>();
char[] charArray1 = line.toCharArray();
for (int i = 0; i < length; i++) {
char currentChar = charArray1[i];
chars.put(currentChar, chars.containsKey(currentChar) ? chars.get(currentChar) + 1 : 1);
}
for (Map.Entry<Character, Integer> entry : chars.entrySet()) {
if (entry.getValue() == 1) {
result1 = entry.getKey().toString();
break;
}
}
long end = System.currentTimeMillis();
System.out.println("1st test:\n result: " + result1 + "\n time: " + (end - start));
start = System.currentTimeMillis();
for (int i = 0; i < length; i++) {
String current = Character.toString(line.charAt(i));
String left = line.substring(0, i);
if (!left.contains(current)) {
String right = line.substring(i + 1);
if (!right.contains(current)) {
result2 = current;
break;
}
}
}
end = System.currentTimeMillis();
System.out.println("2nd test:\n result: " + result2 + "\n time: " + (end - start));
start = System.currentTimeMillis();
for (int i = 0; i < length; i++) {
char currentChar = line.charAt(i);
if (line.indexOf(currentChar) == line.lastIndexOf(currentChar)) {
result3 = Character.toString(currentChar);
break;
}
}
end = System.currentTimeMillis();
System.out.println("3rd test:\n result: " + result3 + "\n time: " + (end - start));
start = System.currentTimeMillis();
char[] charArray4 = line.toCharArray();
for (int i = 0; i < length; i++) {
char currentChar = charArray4[i];
int count = 0;
for (int j = 0; j < length; j++) {
if (currentChar == charArray4[j] && i != j) {
count++;
break;
}
}
if (count == 0) {
result4 = Character.toString(currentChar);
break;
}
}
end = System.currentTimeMillis();
System.out.println("4th test:\n result: " + result4 + "\n time: " + (end - start));
start = System.currentTimeMillis();
for (int i = 0; i < length; i++) {
char currentChar = line.charAt(i);
int count = 0;
for (int j = 0; j < length; j++) {
if (currentChar == line.charAt(j) && i != j) {
count++;
break;
}
}
if (count == 0) {
result5 = Character.toString(currentChar);
break;
}
}
end = System.currentTimeMillis();
System.out.println("5th test:\n result: " + result5 + "\n time: " + (end - start));
return result1;
}
And time results (5 times):
1st test:
result: g
time: 13, 12, 12, 12, 14
2nd test:
result: g
time: 55, 56, 59, 70, 59
3rd test:
result: g
time: 2, 3, 2, 2, 3
4th test:
result: g
time: 3, 3, 2, 3, 3
5th test:
result: g
time: 6, 5, 5, 5, 6
public static char NonReapitingCharacter(String str) {
Set<Character> s = new HashSet();
char ch = '\u0000';
for (char c : str.toCharArray()) {
if (s.add(c)) {
if (c == ch) {
break;
} else {
ch = c;
}
}
}
return ch;
}
Okay I misread the question initially so here's a new solution. I believe is this O(n). The contains(Object) of HashSet is O(1), so we can take advantage of that and avoid a second loop. Essentially if we've never seen a specific char before, we add it to the validChars as a potential candidate to be returned. The second we see it again however, we add it to the trash can of invalidChars. This prevents that char from being added again. At the end of the loop (you have to loop at least once no matter what you do), you'll have a validChars hashset with n amount of elements. If none are there, then it will return null from the Character class. This has a distinct advantage as the char class has no good way to return a 'bad' result so to speak.
public static Character findNonRepeatingChar(String x)
{
HashSet<Character> validChars = new HashSet<>();
HashSet<Character> invalidChars = new HashSet<>();
char[] array = x.toCharArray();
for (char c : array)
{
if (validChars.contains(c))
{
validChars.remove(c);
invalidChars.add(c);
}
else if (!validChars.contains(c) && !invalidChars.contains(c))
{
validChars.add(c);
}
}
return (!validChars.isEmpty() ? validChars.iterator().next() : null);
}
If you are only interested for characters in the range a-z (lowercase as OP requested in comments), you can use this method that requires a minimum extra storage of two bits per character Vs a HashMap approach.
/*
* It works for lowercase a-z
* you can scale it to add more characters
* eg use 128 Vs 26 for ASCII or 256 for extended ASCII
*/
public static char getFirstNotRepeatedChar(String input) {
boolean[] charsExist = new boolean[26];
boolean[] charsNonUnique = new boolean[26];
for (int i = 0; i < input.length(); i++) {
int index = 'z' - input.charAt(i);
if (!charsExist[index]) {
charsExist[index] = true;
} else {
charsNonUnique[index] = true;
}
}
for (int i = 0; i < input.length(); i++) {
if (!charsNonUnique['z' - input.charAt(i)])
return input.charAt(i);
}
return '?'; //example return of no character found
}
In case of two loops (not nested) the time complexity would be O(n).
The second solution mentioned in the question can be implemented as:
We can use string characters as keys to a map and maintain their count. Following is the algorithm.
1.Scan the string from left to right and construct the count map.
2.Again, scan the string from left to right and check for count of each character from the map, if you find an element who’s count is 1, return it.
package com.java.teasers.samples;
import java.util.Map;
import java.util.HashMap;
public class NonRepeatCharacter {
public static void main(String[] args) {
String yourString = "Hi this is javateasers";//change it with your string
Map<Character, Integer> characterMap = new HashMap<Character, Integer>();
//Step 1 of the Algorithm
for (int i = 0; i < yourString.length(); i++) {
Character character = yourString.charAt(i);
//check if character is already present
if(null != characterMap.get(character)){
//in case it is already there increment the count by 1.
characterMap.put(character, characterMap.get(character) + 1);
}
//in case it is for the first time. Put 1 to the count
else
characterMap.put(character, 1);
}
//Step 2 of the Algorithm
for (int i = 0; i < yourString.length(); i++) {
Character character = yourString.charAt(i);
int count = characterMap.get(character);
if(count == 1){
System.out.println("character is:" + character);
break;
}
}
}
}
public char firstNonRepeatedChar(String input) {
char out = 0;
int length = input.length();
for (int i = 0; i < length; i++) {
String sub1 = input.substring(0, i);
String sub2 = input.substring(i + 1);
if (!(sub1.contains(input.charAt(i) + "") || sub2.contains(input
.charAt(i) + ""))) {
out = input.charAt(i);
break;
}
}
return out;
}
Since LinkedHashMap keeps the order of insertion
package com.company;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static void main(String[] argh) {
Scanner sc = new Scanner(System.in);
String l = sc.nextLine();
System.out.println(firstCharNoRepeated(l));
}
private static String firstCharNoRepeated(String l) {
Map<String, Integer> chars = new LinkedHashMap();
for(int i=0; i < l.length(); i++) {
String c = String.valueOf(l.charAt(i));
if(!chars.containsKey(c)){
chars.put(c, i);
} else {
chars.remove(c);
}
}
return chars.keySet().iterator().next();
}
}
Few lines of code, works for me.
public class FirstNonRepeatingCharacter {
final static String string = "cascade";
public static void main(String[] args) {
char[] charArr = string.toCharArray();
for (int i = 0; charArr.length > i; i++) {
int count = 0;
for (int j = 0; charArr.length > j; j++) {
if (charArr[i] == charArr[j]) {
count++;
}
}
if (count == 1){
System.out.println("First Non Repeating Character is: " + charArr[i]);
break;
}
}
}
}
Constraint for this solution:
O(n) time complexity. My solution is O(2n), follow Time Complexity analysis,O(2n) => O(n)
import java.util.HashMap;
public class FindFirstNonDuplicateCharacter {
public static void main(String args[]) {
System.out.println(findFirstNonDuplicateCharacter("abacbcefd"));
}
private static char findFirstNonDuplicateCharacter(String s) {
HashMap<Character, Integer> chDupCount = new HashMap<Character, Integer>();
char[] charArr = s.toCharArray();
for (char ch: charArr) { //first loop, make the tables and counted duplication by key O(n)
if (!chDupCount.containsKey(ch)) {
chDupCount.put(ch,1);
continue;
}
int dupCount = chDupCount.get(ch)+1;
chDupCount.replace(ch, dupCount);
}
char res = '-';
for(char ch: charArr) { //second loop, get the first duplicate by count number, O(2n)
// System.out.println("key: " + ch+", value: " + chDupCount.get(ch));
if (chDupCount.get(ch) == 1) {
res = ch;
break;
}
}
return res;
}
}
Hope it help
char firstNotRepeatingCharacter(String s) {
for(int i=0; i< s.length(); i++){
if(i == s.lastIndexOf(s.charAt(i)) && i == s.indexOf(s.charAt(i))){
return s.charAt(i);
}
}
return '_';
}
String a = "sampapl";
char ar[] = a.toCharArray();
int dya[] = new int[256];
for (int i = 0; i < dya.length; i++) {
dya[i] = -1;
}
for (int i = 0; i < ar.length; i++) {
if (dya[ar[i]] != -1) {
System.out.println(ar[i]);
break;
} else {
dya[ar[i]] = ar[i];
}
}
This is solution in python:
input_str = "interesting"
#input_str = "aabbcc"
#input_str = "aaaapaabbcccq"
def firstNonRepeating(param):
counts = {}
for i in range(0, len(param)):
# Store count and index repectively
if param[i] in counts:
counts[param[i]][0] += 1
else:
counts[param[i]] = [1, i]
result_index = len(param) - 1
for x in counts:
if counts[x][0] == 1 and result_index > counts[x][1]:
result_index = counts[x][1]
return result_index
result_index = firstNonRepeating(input_str)
if result_index == len(input_str)-1:
print("no such character found")
else:
print("first non repeating charater found: " + input_str[result_index])
Output:
first non repeating charater found: r
import java.util.*;
public class Main {
public static void main(String[] args) {
String str1 = "gibblegabbler";
System.out.println("The given string is: " + str1);
for (int i = 0; i < str1.length(); i++) {
boolean unique = true;
for (int j = 0; j < str1.length(); j++) {
if (i != j && str1.charAt(i) == str1.charAt(j)) {
unique = false;
break;
}
}
if (unique) {
System.out.println("The first non repeated character in String is: " + str1.charAt(i));
break;
}
}
}
}
public class GFG {
public static void main(String[] args) {
String s = "mmjjjjmmn";
for (char c : s.toCharArray()) {
if (s.indexOf(c) == s.lastIndexOf(c)) {
System.out.println("First non repeated is:" + c);
break;
}
}
}
output = n
Non Repeated Character String in Java
public class NonRepeatedCharacter {
public static void main(String[] args) {
String s = "ffeeddbbaaclck";
for (int i = 0; i < s.length(); i++) {
boolean unique = true;
for (int j = 0; j < s.length(); j++) {
if (i != j && s.charAt(i) == s.charAt(j)) {
unique = false;
break;
}
}
if (unique) {
System.out.println("First non repeated characted in String \""
+ s + "\" is:" + s.charAt(i));
break;
}
}
}
}
Output:
First non repeated characted in String "ffeeddbbaaclck" is:l
For More Details
In this coding i use length of string to find the first non repeating letter.
package com.string.assingment3;
import java.util.Scanner;
public class FirstNonRepetedChar {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter a String : ");
String str = in.next();
char[] ch = str.toCharArray();
int length = ch.length;
int x = length;
for(int i=0;i<length;i++) {
x = length-i;
for(int j=i+1;j<length;j++) {
if(ch[i]!=ch[j]) {
x--;
}//if
}//inner for
if(x==1) {
System.out.println(ch[i]);
break;
}
else {
continue;
}
}//outer for
}
}// develope by NDM
In Kotlin
fun firstNonRepeating(string: String): Char?{
//Get a copy of the string
var copy = string
//Slice string into chars then convert them to string
string.map { it.toString() }.forEach {
//Replace first occurrance of that character and check if it still has it
if (copy.replaceFirst(it,"").contains(it))
//If it has the given character remove it
copy = copy.replace(it,"")
}
//Return null if there is no non-repeating character
if (copy.isEmpty())
return null
//Get the first character from what left of that string
return copy.first()
}
https://pl.kotl.in/KzL-veYNZ
public static void firstNonRepeatFirstChar(String str) {
System.out.println("The given string is: " + str);
for (int i = 0; i < str.length(); i++) {
boolean unique = true;
for (int j = 0; j < str.length(); j++) {
if (i != j && str.charAt(i) == str.charAt(j)) {
unique = false;
break;
}
}
if (unique) {
System.out.println("The first non repeated character in String is: " + str.charAt(i));
break;
}
}
}
Using Set with single for loop
public static Character firstNonRepeatedCharacter(String str) {
Character result = null;
if (str != null) {
Set<Character> set = new HashSet<>();
for (char c : str.toCharArray()) {
if (set.add(c) && result == null) {
result = c;
} else if (result != null && c == result) {
result = null;
}
}
}
return result;
}
You can achieve this in single traversal of String using LinkedHashSet as follows:
public static Character getFirstNonRepeatingCharacter(String str) {
Set<Character> result = new LinkedHashSet<>(256);
for (int i = 0; i< str.length(); ++i) {
if(!result.add(str.charAt(i))) {
result.remove(str.charAt(i));
}
}
if(result.iterator().hasNext()) {
return result.iterator().next();
}
return null;
}
For Java;
char firstNotRepeatingCharacter(String s) {
HashSet<String> hs = new HashSet<>();
StringBuilder sb =new StringBuilder(s);
for (int i = 0; i<s.length(); i++){
char c = sb.charAt(i);
if(s.indexOf(c) == i && s.indexOf(c, i+1) == -1 ) {
return c;
}
}
return '_';
}
public class FirstNonRepeatingChar {
public static void main(String[] args) {
String s = "hello world i am here";
s.chars().boxed()
.collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
.entrySet().stream().filter(e -> e.getValue() == 1).findFirst().ifPresent(e->System.out.println(e.getKey()));
}
}
package looping.concepts;
import java.util.Scanner;
public class Line {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter name: ");
String a = sc.nextLine();
int i = 0;
int j = 0;
for (i = 0; i < a.length(); i++) {
char ch = a.charAt(i);
int counter = 0;
// boolean repeat = false;
for (j = 0; j < a.length(); j++) {
if (ch == a.charAt(j)) {
counter++;
}
}
if (counter == 1) {
System.out.print(ch);
}
else
{
System.out.print("There is no non repeated character");
break;
}
}
}
}
import java.util.Scanner;
public class NonRepaeated1
{
public static void main(String args[])
{
String str;
char non_repeat=0;
int len,i,j,count=0;
Scanner s = new Scanner(System.in);
str = s.nextLine();
len = str.length();
for(i=0;i<len;i++)
{
non_repeat=str.charAt(i);
count=1;
for(j=0;j<len;j++)
{
if(i!=j)
{
if(str.charAt(i) == str.charAt(j))
{
count=0;
break;
}
}
}
if(count==1)
break;
}
if(count == 1)
System.out.print("The non repeated character is : " + non_repeat);
}
}
package com.test.util;
public class StringNoRepeat {
public static void main(String args[]) {
String st = "234123nljnsdfsdf41l";
String strOrig=st;
int i=0;
int j=0;
String st1="";
Character ch=' ';
boolean fnd=false;
for (i=0;i<strOrig.length(); i++) {
ch=strOrig.charAt(i);
st1 = ch.toString();
if (i==0)
st = strOrig.substring(1,strOrig.length());
else if (i == strOrig.length()-1)
st=strOrig.substring(0, strOrig.length()-1);
else
st=strOrig.substring(0, i)+strOrig.substring(i+1,strOrig.length());
if (st.indexOf(st1) == -1) {
fnd=true;
j=i;
break;
}
}
if (!fnd)
System.out.println("The first no non repeated character");
else
System.out.println("The first non repeated character is " +strOrig.charAt(j));
}
}

Turn String aaaabbbbddd into a4b4d3

I'm trying to get a head start on practicing interview questions and I came across this one:
Turn String aaaabbbbddd into a4b4d3
You would basically want to convert the existing string into a string with each unique character occurrence and the number of times the character occurs.
This is my solution but I think it could be refined into something more elegant:
String s = "aaaabbbbddd";
String modified = "";
int len = s.length();
char[] c = s.toCharArray();
int count = 0;
for (int i = 0; i < len; i++) {
count = 1;
for (int j = i + 1; j < len; j++) {
if (c[i] == ' ') {
break;
}
if (c[i] == c[j]) {
count++;
c[j] = ' ';
}
}
if (c[i] != ' ') {
modified += c[i] + "" + count;
}
}
System.out.println(modified);
Does anyone have any other suggestions for a solution?
Employ a Map<Character, Integer> instead. Attempt to insert the new character into the map; if it already exists, then increment the value for that particular character.
Example:
Map<Character, Integer> countMap = new HashMap<>();
if(!countMap.containsKey('a')) {
countMap.put('a', 1);
} else {
countMap.put('a', countMap.get('a') + 1);
}
To add on to #Makoto's wonderful answer, in your situation, I would use a TreeMap instead of a HashMap. A TreeMap will allow you to print in alphabetical order. I have also added the print code to show you how it would look. It's fully runnable.
import java.util.Map;
import java.util.TreeMap;
public class MapPractice {
public static void main(String[] args) {
Map<Character, Integer> map = new TreeMap<>();
String blah = "aaaabbbbddd";
for (int i = 0; i < blah.length(); i++) {
char c = blah.charAt(i);
if (!map.containsKey(c)) {
map.put(c, 1);
} else {
map.put(c, (map.get(c) + 1));
}
}
for (Map.Entry<Character, Integer> entry: map.entrySet()) {
System.out.print(entry.getKey() + "" + entry.getValue());
}
}
}
Output with TreeMap: a4b4d3
Output with HashMap: d3b4a4
My version
StringBuilder sb = new StringBuilder();
int count = 0;
char last = s.charAt(0);
for(char c : s.toCharArray()) {
if (c == last) {
count++;
} else {
sb.append(last).append(count);
count = 0;
last = c;
}
}
if (count != 0) {
sb.append(last).append(count);
}
System.out.println(sb);
Here is the code that I tried.
I think you can't ask for a simpler code than this.
String s = "aaaabbbbddd", modified = "";
int len = s.length(), i = 0, j = i + 1, count = 1;
char[] c = s.toCharArray();
for (; i < len; i = j) {
count = 1;
for (; j < len; j++)
if (c[i] == c[j])
count++;
else {
j++;
break;
}
modified += c[i] + "" + count;
}
System.out.println(modified);
Hope you find this useful.
Method 1
Scanner scan = new Scanner(System.in);
System.out.print("Enter the string : ");
String str = scan.nextLine();
char c;
char[] charArr = str.toCharArray();
LinkedHashMap<Character,Integer> map = new LinkedHashMap<>();
for(int i = 0 ; i < charArr.length ; i++)
{
c = charArr[i];
if(map.containsKey(c) || map.containsKey(c-32))
{
if(c<97)
{
map.put(c,map.get(c)+1);
}
else
{
map.put(c,map.get(c)+1);
}
}
else
{
map.put((char)(c+32),1);
}
}
for(Map.Entry e : map.entrySet())
{
System.out.print(""+e.getKey()+""+e.getValue());
}
Method 2
Scanner scan = new Scanner(System.in);
System.out.print("Enter the string : ");
String str = scan.nextLine();
String newStr = "";
char c;
int count = 1;
char[] charArr = str.toCharArray();
for(int i = 0 ; i < charArr.length ; i++)
{
c = charArr[i];
if(i>0)
{
if ( c == charArr[i-1] || c == (char)(charArr[i-1]+32) )
{
count++;
}
else
{
if(c < 97)
{
newStr = newStr + count;
count = 1;
newStr = newStr + (char)(c+32);
}
else
{
newStr = newStr + count;
count = 1;
newStr = newStr + c;
}
}
}
else
{
if(c < 97)
{
newStr = newStr + (char)(c+32);
}
else
{
newStr = newStr + (char)c;
}
}
}
newStr = newStr + count;
System.out.print(newStr);
import java.io.*;
import java.util.*;
public class Main
{
public static void main(String[] args) {
Scanner S=new Scanner(System.in);
String in=S.next();
int count=1;
String out="";
for(int i=0;i<in.length()-1;){
out+=in.charAt(i+1);
count=1;
if(in.charAt(i)!=in.charAt(i+1)){
out+=count;
i++;
}else{
while(i<in.length()-1){
if(in.charAt(i)==in.charAt(i+1)){
count++;
i++;
}
else{
i++;
break;
}
}
out+=count;
}
}
System.out.println(out);
}
}
Here is my solution
public String countChars(String in){
LinkedHashMapMap<Character, Integer> map = new LinkedHashMap<Character, Integer>();
for(char c: in.toCharArray()){
Integer count = map.get(c);
if(count==null){
count=0;
}
count++;
map.put(c,count);
}
String out ="";
for(Entry<Character, Integer> e : map.entrySet()){
out += e.getKey()+e.getValue();
}
return out;
}

how can i calculate the number of specific chars in a string?

Given a string how can i figure out the number of times each char in a string repeats itself
ex: aaaabbaaDD
output: 4a2b2a2D
public static void Calc() {
Input();
int count = 1;
String compressed = "";
for (int i = 0; i < input.length(); i++) {
if (lastChar == input.charAt(i)) {
count++;
compressed += Integer.toString(count) + input.charAt(i);
}
else {
lastChar = input.charAt(i);
count = 1;
}
}
System.out.println(compressed);
}
What you'r looking for is "Run-length encoding". Here is the working code to do that;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RunLengthEncoding {
public static String encode(String source) {
StringBuffer dest = new StringBuffer();
// iterate through input string
// Iterate the string N no.of.times where N is size of the string to find run length for each character
for (int i = 0; i < source.length(); i++) {
// By default run Length for all character is one
int runLength = 1;
// Loop condition will break when it finds next character is different from previous character.
while (i+1 < source.length() && source.charAt(i) == source.charAt(i+1)) {
runLength++;
i++;
}
dest.append(runLength);
dest.append(source.charAt(i));
}
return dest.toString();
}
public static String decode(String source) {
StringBuffer dest = new StringBuffer();
Pattern pattern = Pattern.compile("[0-9]+|[a-zA-Z]");
Matcher matcher = pattern.matcher(source);
while (matcher.find()) {
int number = Integer.parseInt(matcher.group());
matcher.find();
while (number-- != 0) {
dest.append(matcher.group());
}
}
return dest.toString();
}
public static void main(String[] args) {
String example = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
System.out.println(encode(example));
System.out.println(decode("1W1B1W1B1W1B1W1B1W1B1W1B1W1B"));
}
}
This program first finds the unique characters or numbers in a string. It will then check the frequency of occurance.
This program considers capital and small case as different characters. You can modify it if required by using ignorecase method.
import java.io.*;
public class RunLength {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
System.out.println("Please enter the string");
String str = br.readLine();//the input string is in str
calculateFrequency(str);
}
private static void calculateFrequency(String str) {
int length = str.length();
String characters[] = new String[length];//to store all unique characters in string
int frequency[] = new int[length];//to store the frequency of the characters
for (int i = 0; i < length; i++) {
characters[i] = null;
frequency[i] = 0;
}
//To get unique characters
char temp;
String temporary;
int uniqueCount = 0;
for (int i = 0; i < length; i++) {
int flag = 0;
temp = str.charAt(i);
temporary = "" + temp;
for (int j = 0; j < length; j++) {
if (characters[j] != null && characters[j].equals(temporary)) {
flag = 1;
break;
}
}
if (flag == 0) {
characters[uniqueCount] = temporary;
uniqueCount++;
}
}
// To get the frequency of the characters
for(int i=0;i<length;i++){
temp=str.charAt(i);
temporary = ""+temp;
for(int j=0;i<characters.length;j++){
if(characters[j].equals(temporary)){
frequency[j]++;
break;
}
}
}
// To display the output
for (int i = 0; i < length; i++) {
if (characters[i] != null) {
System.out.println(characters[i]+" "+frequency[i]);
}
}
}}
Some hints: In your code sample you also need to reset count to 0 when the run ends (when you update lastChar). And you need to output the final run (after the loop is done). And you need some kind of else or continue between the two cases.
#Balarmurugan k's solution is better - but just by improving upon your code I came up with this -
String input = "aaaabbaaDD";
int count = 0;
char lastChar = 0;
int inputSize = input.length();
String output = "";
for (int i = 0; i < inputSize; i++) {
if (i == 0) {
lastChar = input.charAt(i);
count++;
} else {
if (lastChar == input.charAt(i)) {
count++;
} else {
output = output + count + "" + lastChar;
count = 1;
lastChar = input.charAt(i);
}
}
}
output = output + count + "" + lastChar;
System.out.println(output);

Categories