to find repetative character in string - java

How can I find distinct repetitive character in string using Java.
For the string 4567895443577
Here, the first distinct repetitive character is 5
Ip:n:1 output:4
n=2 op=5
n=3 op=7
n=4 op=doest exist

create HashSet and HashMap: set,map and int count=0,
iterate over the string, and add each character and its index. at the end - each character's value will be the LAST index.
iterate over the String again, and check if the index is as appears in the map. if it does (or the character appears in the set) - ignore it.
if a character is not in the set, and index as is and as in map don't match - increase count (until it reaches n).
complexity: O(n)
public static Character findN(String str,int n) {
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int len = str.length();
for (int i=0;i<len;i++) {
map.put(str.charAt(i),i);
}
int count=0;
HashSet<Character> set = new HashSet<Character>();
for (int i=0;i<len;i++) {
if (set.contains(str.charAt(i))) continue;
if (map.get(str.charAt(i)) != i) {
count++;
if (count == n) return str.charAt(i);
set.add(str.charAt(i));
}
}
return null; //it does not exist
}

This should work:
public static char findChar(String s, int length) {
int[] counts = new int[10];
// iterate over the letters and increment the count
int stringLength = s.length();
for(int i = 0; i < stringLength; i++ ) {
char c = s.charAt(i);
int value = Character.getNumericValue(c);
counts[value]++;
}
int counter = 0; // how many chars repeated so far
for(int i = 0; i < stringLength; i++ ) {
char c = s.charAt(i);
int value = Character.getNumericValue(c);
if(counts[value] >= 2) {
counts[value] = -1; // do not count this twice
counter++;
if(counter == length) {
return c;
}
}
}
return '\u0000'; // null char
}

This can be done by the following code.
I have used HashMap keys as an input characters and value as a counter.
String str = "4567895443577";
char[] chars = str.toCharArray();
HashMap<Character, Integer> charMap = new HashMap<Character, Integer>();
for( char c : chars )
{
if( charMap.containsKey( c ) ){
charMap.put(c, charMap.get(c) + 1 );
}else{
charMap.put(c, 1);
}
}
for( Entry<Character, Integer> entry : charMap.entrySet() )
{
System.out.println( "Character '"+entry.getKey()+"' is repeated for '"+entry.getValue()+"' times." );
}

You should create a HashSet which implements Set Interface.
A collection that contains no duplicate elements. More formally, sets
contain no pair of elements e1 and e2 such that e1.equals(e2), and at
most one null element. As implied by its name, this interface models
the mathematical set abstraction.

/*
* Ex-OR basic : 0^0 = 0, 0^1 = 1, 1^0 = 1, 1^1 = 0
*
Ex-ORing bits of all characters in String nums = "4567895443577"
i Operation Bitwise operation Result(bin) Result(Dec)
0 4 ^ 5 ...arr[0]^arr[1] 100 ^ 101 001 1
//NOTE : first occurence as result = 1 should be skipped
----------------------------------------------------------------------------
Result(i-1) arr[i]
for:
1 1 ^ 5 001 ^ 101 100 4
2 4 ^ 6 100 ^ 110 010 2
3 2 ^ 7 010 ^ 111 101 5
4 5 ^ 8 0101 ^ 1000 1101 13
5 13 ^ 9 1101 ^ 1001 0100 4
6 5 ^ 4 0101 ^ 0100 0001 1
// break "for" found repeated element. return 5
* */
public class RepeatedNumber {
public static void main(String args[]) {
String nums = "4567895443577";
char repeated = (char) findRepeated(nums.toCharArray()) ;
System.out.println("result ="+repeated);
}
public static int findRepeated(char arr[]) {
int result = arr[0]^arr[1];
int repeated = arr[0];
//find out number repeated more than once in array
if(result != 0) {
for(int i = 1; i < arr.length; i++) {
result = result ^ arr[i];
if(result == 1 || arr[i] == arr[i-1]) {
repeated = arr[i];
break;
}
}
}
return repeated;
}
}

Related

How do I make a program that counts the occurrence of each individual digit between 1 and 100?

I'm making a program that counts how many times each digit (0-9) occurs in each number between 1 to 100. At the end it will say something like:
The digit 0 showed up ____ times between 1-100
The digit 1 showed up ____ times between 1-100
and so forth.
This is what I have:
public class CountEachDigit {
public static void main(String[] args) {
int counter =0;
int[] digit = new int[10];
for (int i=1;i<=100;i++) {
for (int j=0;j<=9;j++){
try{
String a = String.valueOf(i);
String b = String.valueOf(j);
if (b.equals(a.charAt(0)))
counter++;
digit[j]=counter;
} catch (Exception e){
continue;
}
try{
String a = String.valueOf(i);
String b = String.valueOf(j);
if (b.equals(a.charAt(1)))
counter++;
digit[j]=counter;
} catch (Exception e){
continue;
}
try{
String a = String.valueOf(i);
String b = String.valueOf(j);
if (b.equals(a.charAt(2)))
counter++;
digit[j]=counter;
} catch (Exception e){
continue;
}
}
}
for (int j =0;j<=9;j++){
System.out.println("The number "+j+" appears "+digit[j]+" times between 1 - 100.");
}
}
}
I tried changing the charAt each digit to a String to count the occurrence using the try and catch. No dice so far.
You do not need a string operations. You have to use x % 10 to get the last digit, and then x \= 10, to remove this last digit.
public class CountEachDigit {
public static void main(String... args) {
final int lo = 1;
final int hi = 100;
int[] digits = countDigits(lo, hi);
for (int i = 0; i < 10; i++)
System.out.format("The number %d appears %d times between %d - %d.\n", i, digits[i], lo, hi);
}
private static int[] countDigits(int lo, int hi) {
int[] digits = new int[10];
for (int i = lo; i <= hi; i++) {
int val = i;
do {
digits[val % 10]++;
} while ((val /= 10) > 0);
}
return digits;
}
}
Demo:
The number 0 appears 11 times between 1 - 100.
The number 1 appears 21 times between 1 - 100.
The number 2 appears 20 times between 1 - 100.
The number 3 appears 20 times between 1 - 100.
The number 4 appears 20 times between 1 - 100.
The number 5 appears 20 times between 1 - 100.
The number 6 appears 20 times between 1 - 100.
The number 7 appears 20 times between 1 - 100.
The number 8 appears 20 times between 1 - 100.
The number 9 appears 20 times between 1 - 100.
Have an array with int[10] to count the occurrences for each digit.
Then have a function that traverses a string and for each digit it finds increases the correct field in the array.
Then have a loop over numbers from 1 to 100 which converts that number to string and feeds it into the function.
Finally print the array values.
In code this may look like
public class Test {
static int[] occurrences = new int[10];
static void checkOccurrences(String s) {
for (char c: s.toCharArray()) {
if (Character.isDigit(c)) {
occurrences[ c - '0' ]++;
}
}
}
public static void main(String[] args) {
for (int i=1; i<=100; i++) {
String s = String.valueOf(i);
System.out.println("checking "+s);
checkOccurrences(s);
}
System.out.println(Arrays.toString(occurrences));
}
}
and it prints
checking 1
checking 2
checking 3
...
checking 99
checking 100
[11, 21, 20, 20, 20, 20, 20, 20, 20, 20]
In case you or future readers want to see a stream approach, which I doubt, here's what I did just for fun: Stream over the range [1 - 100], convert and map to String, split each String at each charachter such that, for example "42" becomes a stream of "4" and "2", collect to map using digit as key and count of occurrence as value and finally print.
import java.util.Arrays;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
// ...
public static void main(String[] args) {
IntStream.rangeClosed(1, 100)
.mapToObj(String::valueOf)
.flatMap(s -> Arrays.stream(s.split("")))
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.forEach((k,v) -> System.out.printf("The digit %s showed up %d times between 1-100%n", k, v));
}
Instead of converting a number to string and then loop over its digits, you can also take the remainder by 10, i.e., the last digit, and then divide the number by 10 to "shift" it to the right.
For example, 45 % 10 == 5, and 45 / 10 == 4.
After you exit the while loop, your number is a single-digit number, so you have to count again that digit.
public class CountEachDigit {
public static void main(String[] args) {
int[] digits_count = new int[10];
int min = 1;
int max = 100;
for (int i = min; i <= max; ++i) {
int number = i;
while (number > 9) {
int last_digit = number % 10;
digits_count[last_digit] += 1;
number /= 10;
}
digits_count[number] += 1;
}
for (int i = 0; i < 10; i++) {
int count = digits_count[i];
System.out.println("Digit " + i + " appears " + count + " times in range [" + min + ", " + max + "]");
}
}
}
Using strings:
for (int i = 1; i <= 100; i++) {
String num = String.valueOf(i);
for(int j=0;j<num.length();j++){
//substracting 0 to get the integer value
counts[num.charAt(j)-'0']++;
}
}
for (int i = 0; i < 10; i++) {
System.out.println("The digit " + i + " showed up " + counts[i] + " times between 1-100.");
}
You can do it using by streaming and collecting in a map.
allocate a map to hold the counts
stream the values from 1 to 100 inclusive
within mapMulti
get the last digit by using the remainder % operator
accept the digit and place on the stream
expose the next digit by dividing by 10
Now collect the digits in the map, creating a frequency count as they occur. Each digit will the the key and the value will be the count.
Map<Integer, Integer> counts = IntStream.rangeClosed(1, 100)
.mapMulti((val, consumer) -> {
while (val > 0) {
consumer.accept(val % 10);
val /= 10;
}
}).boxed()
.collect(Collectors.toMap(i -> i, i -> 1, Integer::sum));
counts.forEach((digit, count) -> System.out
.println(digit + " occurs " + count + " times."));
prints
0 occurs 11 times.
1 occurs 21 times.
2 occurs 20 times.
3 occurs 20 times.
4 occurs 20 times.
5 occurs 20 times.
6 occurs 20 times.
7 occurs 20 times.
8 occurs 20 times.
9 occurs 20 times.

Determine if an array of numbers can divided into a set of k consecutive numbers

Given some array nums and a positive integer k, determine if its possible to divide this array into sets of k consecutive numbers.
Example:
nums = [1,2,3,4] k = 2
Output true since [1,2], [3, 4]
My thoughts is that that size of the array nums has to be divisible by the integer k. But when I use that as the test I fail for this test case:
[15,16,17,18,19,16,17,18,19,20,6,7,8,9,10,3,4,5,6,20] k = 5
I get true but the answer is false and I am not sure why. Any ideas?
Here is my code:
int n = nums.size();
if(n % k == 0)
return true;
return false;
Here are more examples if that helps:
The problem can be solved by sorting the array, counting duplicates, and then verifying the consecutive sequences.
Consider example 2, where k=3 and the array is
[3,2,1,2,3,4,3,4,5,9,10,11]
After sorting:
[1,2,2,3,3,3,4,4,5,9,10,11]
After counting duplicates (the top line has the unique numbers in the array, the bottom line has the duplicate count for each number):
1 2 3 4 5 9 10 11
1 2 3 2 1 1 1 1
Now check the sequences. The lowest number is 1, so the sequence [1,2,3] must exist in the array, or the output is false. 1, 2, and 3 all have non-zero counts, so the array does contain that sequence. Update the counts to remove that sequence:
1 2 3 4 5 9 10 11
0 1 2 2 1 1 1 1
Now 2 is the lowest number with a non-zero count, so the next sequence is [2,3,4] and the updated counts are:
1 2 3 4 5 9 10 11
0 0 1 1 1 1 1 1
Finish up with [3,4,5] and [9,10,11]
Solution:
step1. Use TreeMap to store array elements and their occurrence. Treemap helps us to store the element in sorting orders.
step2. Iterate over treemap until it's not empty.
step3. Takeout the first key (firstKey) from treemap and start searching next K consecutive element.
public static boolean isPossibleDivide(int[] arr, int k) {
TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
for (int i = 0; i < arr.length; i++) {
map.put(arr[i], map.get(arr[i]) != null ? map.get(arr[i]) + 1 : 1);
}
while (!map.isEmpty()) {
int firstKey = map.firstKey();
for (int i = 0; i < k; i++) {
int key = firstKey + i;
if (!map.containsKey(key)) {
return false;
} else {
map.put(key, map.get(key) - 1);
if (map.get(key) == 0)
map.remove(key);
}
}
}
return true;
}
bool isPossibleDivide(vector<int>& nums, int k) {
int n = nums.size();
if(n%k != 0)return false;
sort(nums.begin(),nums.end());
map<int,int> m;
for(int i=0;i<n;i++){
m[nums[i]]++;
}
int nu = m.size() - k + 1;
for(auto it=m.begin();it!=m.end();it++){
if(!nu)break;
int x = it->second;
int l=0;
map<int,int> :: iterator s = it;
map<int,int> :: iterator s1 = s ;
while(l<k){
s->second = s->second - x;
s++;
if(s->first - s1->first !=1 && l<k-1)return false;
s1++;
l++;
}
nu--;
}
/*for(auto it=m.begin();it!=m.end();it++){
cout << it->first <<" "<<it->second <<endl;
}*/
for(auto it=m.begin();it!=m.end();it++){
if(it->second != 0) return false;
}
return true;
}
I have done this, but I don't know why it is not working

Having trouble filling an array of binary numbers from an integer

This is the question we were assigned :
Nine coins are placed in a 3x3 matrix with some face up and some face down. You can represent the state of the coins using a 3x3 matrix with values 0 (heads) and 1 (tails). Here are some examples:
0 0 0 1 0 1 1 1 0
0 1 0 0 0 1 1 0 0
0 0 0 1 0 0 0 0 1
Each state can also be represented using a binary number. For example, the preceding matrices correspond to the numbers:
000010000 101001100 110100001
There are a total of 512 possibilities, so you can use decimal numbers 0, 1, 2, 3,...,511 to represent all the states of the matrix.
Write a program that prompts the user to enter a number between 0 and 511 and displays the corresponding matrix with the characters H and T.
I want the method toBinary() to fill the array binaryNumbers. I realized that this does not fill in 0s to the left. I have to think that through but is that the only thing that is the problem?
//https://www.geeksforgeeks.org/java-program-for-decimal-to-binary-conversion/
import java.util.Scanner;
public class HeadsAndTails {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int num = input.nextInt();
int[] binaryNumbers = toBinary(num);
for (int i = 0; i < 9; i++) {
printArr(binaryNumbers);
System.out.print(binaryNumbers[1]);
}
}
public static int[] toBinary(int inputtedNumber) {
int[] binaryNum = new int[9];
int i = 0;
while (inputtedNumber > 0) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
inputtedNumber++;
} return binaryNum;
}
public static void printArr(int[] arr) {
for (int i = 0; i < 9; i++) {
if (arr[i] == 0) {
System.out.print("H ");
} else {
System.out.print("T ");
}
if (arr[i+1] % 3 == 0) {
System.out.println();
} System.out.print(arr[i]);
}
}
}
Looks like you are incrementing the wrong variable in your while loop:
while (inputtedNumber > 0) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
i++; // NOT inputtedNumber
} return binaryNum;
Also note, a new int[9] is probably already initialized to 0, but if not, you could just loop 9 times, rather than until the inputtedNumber is 0:
for (int i = 0; i < 9; i++) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
}
return binaryNum;
Finally, I think your array might be backwards when you're done, so you may need to reverse it or output it in reverse order
I realize this is a homework assignment so you should stick with your current approach. However, sometimes it can be fun to see what can be achieved using the built in features of Java.
The Integer class has a method toBinaryString that's a good starting point:
int n = 23;
String s1 = Integer.toBinaryString(n);
System.out.println(s1);
Output: 10111
But as we can see, this omits leading 0s. We can get these back by making sure our number has a significant digit in the 10th place, using a little bit-twiddling:
String s2 = Integer.toBinaryString(1<<9 | n);
System.out.println(s2);
Output: 1000010111
But now we have a leading 1 that we don't want. We'll strip this off using String.substring, and while we're at it we'll use String.replace to replace 0 with H and 1 with T:
String s3 = Integer.toBinaryString(1<<9 | n).substring(1).replace('0','H').replace('1','T');
System.out.println(s3);
Output: HHHHTHTTT
Now we can print this string in matrix form, again using substring to extract each line and replaceAll to insert the desired spaces:
for(int i=0; i<9; i+=3)
System.out.println(s3.substring(i, i+3).replaceAll("", " ").trim());
Output:
H H H
H T H
T T T
If we're up for a bit of regex wizardry (found here and here) we can do even better:
for(String sl : s3.split("(?<=\\G.{3})"))
System.out.println(sl.replaceAll(".(?=.)", "$0 "));
Putting it all together we get:
int n = 23;
String s3 = Integer.toBinaryString(1<<9 | n).substring(1).replace('0','H').replace('1','T');
for(String s : s3.split("(?<=\\G.{3})"))
System.out.println(s.replaceAll(".(?=.)", "$0 "));

Counting with Java

I have two given Strings: String a = "111" and String b = "132", for these two String I want to achieve this count order:
111
112
121
122
131
132
Other example is if I have two given String like this: String a = "1111" and String b = "1223", I expect this result:
1111
1112
1113
1121
1122
1123
1211
1212
1213
1221
1222
1223
These can be also longer strings like String a = "0100110" and String b = "01101120".
I'm waiting these Strings from user in condition that every character in String a should be lower or equal than the same character position in String b (String a = "11" and String b = "00" <= not allowed)
This is a recursive method till now but it doesn't work very well because it generates number twice or more depending on the input:
public void expand(String l,String h){
for(int i=l.length()-1; i>=0; i--)
{
sb = new StringBuffer(l);
if(charToDigit(l.charAt(i)) < charToDigit(h.charAt(i))) {
sb.replace(i, i+1, inc(sb.charAt(i)));
expand(sb.toString(),h);
System.out.println(sb.toString());
}
}
}
Call the smaller number x and the larger number y. If you calculate y mod 10 (y % 10), you will find the value of the least significant digit, call this n. Similarly, calculate the least significant digit of x, call it m Then, create a temporary variable i which is equal to x initially. Loop until that number is equal to y.
In the body of the loop, first, print i. Then, if the least significant digit of i (again, calculated by i % 10), call it o, is less than n, increment i by one. Otherwise, if o == n, increase i by 10 - n + m. Naturally, if it is ever the case that o > n, something went wrong (i.e. invalid input from the user), since the guarantee was that all digits of x are less than or equal to the corresponding digits in y.
So, in pseudocode:
x = smaller number
y = larger number
n = y % 10
m = x % 10
i = x
while (i <= y):
print i
o = i % 10
if (o < n):
i += 1
else if (o == n):
i += 10 - n + m
Here is my solution
static String l="000";
static String h="232";
static ArrayList<String> combinations = new ArrayList<String>();
static int stringLength= l.length();
for(int i=0; i<rulelength; i++)
{
combinations.add((charToDigit(h.charAt(i)) - charToDigit(l.charAt(i))+1)+"");
}
int number = 1;
for(int i=0; i<combinations.size(); i++)
{
number*=Integer.parseInt(combinations.get(i));
}
int change = Integer.parseInt(combinations.get(combinations.size()-1));
expand(l, h, change, number);
public static void expand(String l, String h, int change, int comb)
{
StringBuffer sb = new StringBuffer(l);
int pos = stringLength-1;
int tmpPos = pos;
for(int i=1; i<=comb; i++)
{
System.out.println(sb.toString());
sb.replace(pos, pos+1, inc(sb.charAt(pos)));
if((i % change)==0) {
for(int j=stringLength-1; j>0; j--)
{
if(charToDigit(sb.charAt(j)) >= (Integer.parseInt(combinations.get(j))-1))
tmpPos = j-1;
else
break;
}
sb.replace(tmpPos, tmpPos+1, inc(sb.charAt(tmpPos)));
for(int j=stringLength-1; j>tmpPos; j--)
{
sb.replace(j, j+1, l.charAt(j)+"");
}
}
}
}

Removing duplicates from sorted Char array

I am trying to take the string below, convert it to an array, sort the array, then take out any duplicates. I have gotten to the sorted part, but when I run this in hopes for the duplicates being removed, it seems to print position instead of the value there.
This is also counting spaces as length, giving me a length of 59 for this.
Can I get some help figuring out what I need to change?
Thank you all!
import java.util.*;
public class Challenge208 {
public static void main(String[] args) {
String numbers = "3 1 3 4 4 1 4 5 2 1 4 4 4 4 1 4 3 2 5 5 2 2 2 4 2 4 4 4 4 1";
char[] chars = numbers.toCharArray();
Arrays.sort(chars);
System.out.println(chars);
int current = chars[0];
boolean found = false;
for (int i = 0; i < chars.length; i++) {
if (current == chars[i] && !found) {
found = true;
}else if (current != chars[i]) {
System.out.print(" " + current);
current = chars[i];
found = false;
}
}
System.out.print(" " + current);
}
}
current should be type char not int. To get rid of the spaces, you could print if current is not a space.
Instead of using array u can use treeset.. It will have a sorted order and no duplicates.. But if in your scenario you need array in that case first your current variable is int instead of char and you are not removing any of the duplicates.you are just printing that whenever you find that char even if that item does not have any duplicates and that only for char[0]
You are not getting the index of the number but its ascii value. For more details: http://www.asciitable.com/
But solution is as follows:
import java.util.*;
public class Challenge208 {
public static void main(String[] args) {
String numbers = "3 1 3 4 4 1 4 5 2 1 4 4 4 4 1 4 3 2 5 5 2 2 2 4 2 4 4 4 4 1";
char[] chars = numbers.toCharArray();
char[] results = new char[10];
Arrays.sort(chars);
System.out.println(chars);
char current = chars[0];
int size = 0;
boolean found = false;
for (int i = 0; i < chars.length; i++) {
if (current == chars[i] && !found) {
found = true;
}else if (current != chars[i]) {
System.out.print(" " + current);
size++;
current = chars[i];
found = false;
}
}
System.out.print(" " + current);
System.out.print("\n"+size);
}
}

Categories

Resources