Why are my map values incorrect? - java

String a = "Some small sample text!";
char[] letters = a.toCharArray();
int[] charvals = new int[letters.length];
for (int i = 0; i<letters.length;i++) {
int curr = (int) letters[i];
charvals[i] = curr;
}
HashMap<Character, Integer> lettermap = new HashMap<Character, Integer>();
Character c;
for (int i = 0; i<letters.length; i++) {
c = letters[i];
if (lettermap.containsKey(c)) {
lettermap.put(c, lettermap.get(c) + 1); }
else {
lettermap.put(c, 1); }}
for (int i = 0; i < charvals.length; i++) {
if (charvals[i] !=32) {
c = letters[i];
System.out.println(lettermap.get(c));
}
1 1 3 3 2 3 2 3 3 2 2 3 1 3 3 2 3 1 2 1
This is the output, horizontally for space concerns. I should only have 3 "3s" or letters that appear 3 or more times, but I get 9. Can anybody tell me why?
It is easy to see on the 3rd item of output. The key is 'm' in my String and it is the first time it is appearing in the map yet the value is 3 and not 1. Why is this happening?

for (int i = 0; i < charvals.length; i++) {
if (charvals[i] !=32) {
c = letters[i];
System.out.println(lettermap.get(c));
}
This goes through every character in the original string -- not uniqued -- and prints outs its count in the map. So if there are three 'c's in the string, it'll print out the count (3) for 'c' three times.
You probably want to iterate over lettermap.entrySet() instead.

Your algorithm is ok really, the only problem is in the output. You are taking individual characters of your input string and outputting their counts, like this:
S o m e s m a l l s a m p l e t e x t
1 1 3 3 2 3 2 3 3 2 2 3 1 3 3 2 3 1 2
Try using lettermap.keySet() instead:
for (Character c2 : lettermap.keySet()) {
System.out.printf("%s - %s\n", c2, lettermap.get(c2));
}

Your program currently only outputs the final counts for the characters present in your String.
To print a running total, you would print the value present in the Map after the value is changed by adding a print statement to your second for loop, like so:
for (int i = 0; i < letters.length; i++) {
c = letters[i];
if (lettermap.containsKey(c)) {
lettermap.put(c, lettermap.get(c) + 1);
} else {
lettermap.put(c, 1);
}
System.out.print(lettermap.get(c) + " ");
}
This prints the following output: 1 1 1 1 1 1 2 1 1 2 2 2 2 3 1 3 2 3 1 3 1 2 1
If you then add some logic to print the character that is being counted, the following is returned:
{'S'=1, 'o'=1, 'm'=1, 'e'=1, ' '=1, 's'=1, 'm'=2, 'a'=1, 'l'=1, 'l'=2, ' '=2, 's'=2, 'a'=2, 'm'=3, 'p'=1, 'l'=3, 'e'=2, ' '=3, 't'=1, 'e'=3, 'x'=1, 't'=2, '!'=1}

Just going to leave this here for anyone interested:
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
public class CharacterCount {
public static void main(String[] args) {
print("Some small sample text!");
}
public static void print(String str) {
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
for (Character c : str.toCharArray()) {
map.put(c, 1 + (map.containsKey(c) ? 1 : 0));
}
List<Character> cList = new ArrayList<Character>(map.keySet());
Collections.sort(cList);
for (Character c : cList) {
System.out.printf("'%c' - %d%n", c, map.get(c));
}
}
}
Prints:
' ' - 2
'!' - 1
'S' - 1
'a' - 2
'e' - 2
'l' - 2
'm' - 2
'o' - 1
'p' - 1
's' - 2
't' - 2
'x' - 1

Related

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

square of character inside square of another character in java

i want to print a square of character in this format basad on the the number of lines
for example :
number of lines : 4
output :
a a a a
a b b a
a b b a
a a a a
number of lines : 5
output :
a a a a a
a b b b a
a b c b a
a b b b a
a a a a a
but i didn't know how to get the result like that and this is my code
import java.util.Scanner;
public class test {
public static void main ( String arugs [] ) {
Scanner read= new Scanner(System.in) ;
System.out.println ( " please inter the number of line : " ) ;
int size = read.nextInt();
int []array = new int[size ];
int c = 97;
for(int i = 0; i < size; ++i) {
for(int j = 0; j < size; ++j){
array[i]= c;
System.out.print( (char)array [i]);}
System.out.println();
}
}
}
}
A funny way to do it :
public static void main(String arugs[]) {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter the number of lines : ");
int size = sc.nextInt();
sc.close();
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
System.out.print((char) ('a' + Math.min(size - j - 1, Math.min(size - i - 1, Math.min(i, j)))) + " ");
}
System.out.println();
}
}
The idea :
we need to calculate the "depth" of a particular point (i, j). The value of this cell will be 'a' + depth
the depth is defined as the minimum distance of the point to any edge of the matrix
In method positionToChar, before the halfway point, the letters increase from a to max char point. At half way and afterwards, the letters decrease from max char point back to a.
There are basically two cases we are covering, even and odd.
For even:
Take the number 4 as input. Bear in mind that we are zero based.
positionToChar(0) -> 'a' + (0 < 4 / 2 ? 0 : 4 - 0 - 1) -> 0 is less than 4 / 2 or 2 so -> 'a' + 0 -> 'a' is returned.
positionToChar(1) -> 'a' + (1 < 4 / 2 ? 1 : 4 - 1 - 1) -> 1 is less than 4 / 2 or 2 so -> 'a' + 1 -> 'b' is returned.
positionToChar(2) -> 'a' + (2 < 4 / 2 ? 2 : 4 - 2 - 1) -> 2 is equal to 4 / 2 or 2 so -> 'a' + 4 - 2 - 1 -> 'b' is returned.
positionToChar(3) -> 'a' + (3 < 4 / 2 ? 3 : 4 - 3 - 1) -> 3 is greater than 4 / 2 or 2 so -> 'a' + 4 - 3 - 1 -> 'a' is returned.
For odd:
Take the number 3 as input. Bear in mind that we are zero based.
positionToChar(0) -> 'a' + (0 < 3 / 2 ? 0 : 3 - 0 - 1) -> 0 is less than 3 / 2 or 1 (truncated because we are using two ints) so -> 'a' + 0 -> 'a' is returned.
positionToChar(1) -> 'a' + (1 < 3 / 2 ? 1 : 3 - 1 - 1) -> 1 is equal to 3 / 2 or 1 (truncated because we are using two ints) so -> 'a' + 3 - 1 - 1 -> 'b' is returned.
positionToChar(2) -> 'a' + (2 < 3 / 2 ? 2 : 3 - 2 - 1) -> 2 is greater than 3 / 2 or 1 (truncated because we are using two ints) so -> 'a' + 3 - 2 - 1 -> 'a' is returned.
In method minChar, for a given position, the lower char of the computed chars for x and y is returned.
Take (x, y) pairs in 3 size:
First layer:
(0, 0) -> In the previous example, we calculated 0 to be 'a'.'a' is returned as is the only char we have.
(0, 1) -> In the previous example, we calculated 0 to be 'a' and 1 to be 'b'. 'a' is returned as it is the smaller of the two.
(0, 2) -> In the previous example, we calculated both 0 and 2 to be 'a'. 'a' is returned as is the only char we have.
Second layer:
(1, 0) -> In the previous example, we calculated 1 to be 'b'and 0 to be 'a'. 'a' is returned as it is the smaller of the two.
(1, 1) -> In the previous example, we calculated 1 to be 'b'. 'b' is returned as is the only char we have.
(1, 2) -> In the previous example, we calculated 1 to be 'b'and 2 to be 'a'. 'a' is returned as it is the smaller of the two.
Third layer:
(2, 0) -> In the previous example, we calculated both 2 and 0 to be 'a'. 'a' is returned as is the only char we have.
(2, 1) -> In the previous example, we calculated 2 to be 'a' and 1 to be 'b'. 'a' is returned as it is the smaller of the two.
(2, 2) -> In the previous example, we calculated 2 to be 'a'.'a' is returned as is the only char we have.
The result:
a a a
a b a
a a a
import java.util.*;
import java.io.*;
class Test {
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
int size = in.nextInt();
String[][] arr = new String[size][size];
String resultLine = "";
for(int x = 0; x < size; x ++) {
for(int y = 0; y < size; y ++) {
arr[x][y] = String.valueOf(minChar(x, y, size));
resultLine += arr[x][y] + " ";
}
resultLine += "\n";
}
System.out.println(resultLine);
}
private static int positionToChar(int position, int size) {
return 'a' + (position < size / 2 ? position : size - position - 1);
}
private static char minChar(int x, int y, int size) {
return (char)Math.min(positionToChar(x, size), positionToChar(y, size));
}
}

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

BIlling system - Programming

I require some input on the below logic.
It is kind of billing system takes the input and has a value associated with it.
A = 2 , 3A = 5
B = 3
C = 1 , 4C = 3
My code , should be such that take ABCCBAACCA , output should be value which is 16.
My solution as of now, I m thinking to count every element in the string, and them mod(modulus) by 3 for A , 4 for C (as in the above case, no need in case of B) every element in order to get the result.
I'm confused what data structure I should be using in order to implement such system.
In pseudocode I believe it would be:
Count all A's, B's and C's
Divide A's by 3 and multiply by 5
Modulo A's by 3 and multiply by 2
Multiply B's by 3
Divide C's by 4 and multiply by 3
Modulo C's by 4
Sum the 5 results.
In Ruby it could like something like this:
input = "ABCCBAACCA"
letters = ["A", "B", "C"]
total = 0
def score(letter,count)
if letter == "A"
((count/3)*5)+((count%3)*2)
elsif letter == "B"
count*3
else letter == "C"
((count/4)*3)+(count%4)
end
end
letters.each do |letter|
puts "#{letter}: #{score(letter, input.count(letter))}"
total += score(letter, input.count(letter))
end
puts "Total: #{total}"
Which produces:
A: 7
B: 6
C: 3
Total: 16
Well, the modulus operator won't help you since you will be getting 0 everytime is a multiple of 3 or 5, depending the letter you are evaluating (if thats what you trying to describe, sorry if i got it wrong).
I believe the easiest way is scanning the string and just adding the values.
When you encounter a third A you just add 1, instead of 2 (because you have to subtract 4, then add 5)
Similarly with C, you just add 0, instead of 1, when you encounter the fourth C.
You need 2 additional variables to keep the instances of A and C, and yes, you can use modulus operator to know if you just arrived to a multiple where you have to add either 1 or 0, depending the case.
Hope this helps a bit.
EDIT:
Here, I did a quick implementation. Feel free to optimize it if you really need it ;)
String value = "ABCCBAACCA";
int numA =0;
int numC =0;
int endResult = 0;
for (int x = 0; x < value.length(); x++)
{
if (value.charAt(x) =='A')
{
numA = numA +1;
endResult = endResult + ((numA%3 == 0)?1:2);
}
else if (value.charAt(x) =='B')
{
endResult = endResult +3;
}
else if (value.charAt(x) =='C')
{
numC = numC +1;
endResult = endResult + ((numC%4 == 0)?0:1);
}
}
System.out.println(endResult); //16 as expected
class CharBucket
attr_accessor :count
def initialize(thresholds)
#thresholds = thresholds
#count = 0
end
def total
#thresholds.inject([0, #count]) do |sum_left, a|
sum = sum_left[0]
left = sum_left[1]
sum += (left / a[0]) * a[1]
left %= a[0]
[sum, left]
end[0]
end
end
a = CharBucket.new({3 => 5, 1 => 2})
b = CharBucket.new({1 => 3})
c = CharBucket.new({4 => 3, 1 => 1})
buckets = {'A' => a, 'B' => b, 'C' => c}
"ABCCBAACCA".each_char{|c| buckets[c].count += 1 }
total = buckets.values.inject(0){|sum, b| sum += b.total} # => 16
Well, I would start with something like this:
public static void main(String[] args) {
// FIXME
String inputString = null;
Map<Character, Integer> map = new HashMap<Character, Integer>();
for (Character c : inputString.toCharArray()) {
map = countCharacters(map, c);
}
}
private static Map<Character, Integer> countCharacters(Map<Character, Integer> map,
Character charatcer) {
map.put(charatcer,
(map.get(charatcer) != null) ? map.get(charatcer) + 1 :
Integer.valueOf(1));
return map;
}
and then introduce #vlasits steps from second to 5th, as this code above is first step in his pseudocode. It counts all characters in your string by making map of "character" : "its Occurences", if there was no such a character before, it puts 1 to the map.

to find repetative character in string

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

Categories

Resources