Why my logic for the below code doesn't work? - java

Can anyone explain me why my code doesn't work, where I am going wrong here?
I have written this code for counting the number 0-9 in an integer in java. If possible please help me with the best solution too.
Well I know it can be efficiently solved by using hash table but I'm looking for a solution which can be understandable by a newbie.
import java.util.*;
class CountNo {
public static void main(String args[] ) {
Scanner a = new Scanner(System.in);
String s = a.next();
char[] b = s.toCharArray();
int S_len = s.length();
int[] count = {0,0,0,0,0,0,0,0,0,0};
for(int i=0;i<S_len;i++)
{
for(int j=0;j<=9;j++)
{
if(b[i]==j)
{
count[j]+=1;
break;
}
}
}
for(int i=0;i<=9;i++)
{
System.out.println(i+" "+count[i]);
}
}
}

because char '0' != 0, it has code 48, so you need to change
if(b[i]==j)
into
if(b[i]-'0'==j)
or you could simplify logic, like:
for(int i = 0; i < S_len; i++)
count[b[i] - '0'] += 1;

You could use a map, in which the key is the digit and the value is the count.
You can learn more about maps here: https://docs.oracle.com/javase/8/docs/api/java/util/Map.html but essentially, a map is a Java object which relates a "key" to a "value", and does not allow duplicates. This is useful if you are trying to keep track of how many times a "key" (in this case, a digit) appears in a string or array.

if(b[i]==j)
{
count[j]+=1;
break;
}
You compare char to int. Try this instead:
if(Character.getNumericValue(b[i]) == j){
count[j]+=1;
break;
}

Related

Writing a Recursive Function in Java to output a set of words in all combinations

I would like to see how to get the following output by using a Java recursive function. Would be great to get some insight on how to go about solving a problem like this. The recursive Java function should take these words: "MIKE", "AND", "IKE" and output each ordering on a separate line such as this.
MIKEANDIKE
MIKEIKEAND
IKEANDMIKE
IKEMIKEAND
ANDIKEMIKE
ANDMIKEIKE
public static void main(String[] args) {
recur(new String[]{"MIKE", "AND", "IKE"}, "", 0);
}
public static void recur(String[] words, String result, int n) {
if (n == words.length) {
System.out.println(result);
return;
}
for (int i = 0; i < words.length; ++i) {
String out = result + words[i];
recur(words, out, n + 1);
}
}
You need to flag in some way the values that you have already used, in this example I use the null for that purpose, but there are other approaches to it (for example using a list and deleting/adding the values, or duplicating the lists themselves).
public static void recur(String[] words, String result, int n) {
if (n == words.length) {
System.out.println(result);
return;
}
String temp;
for (int i = 0; i < words.length; ++i) {
if (null != words[i]) {
String out = result + words[i];
temp = words[i];
words[i] = null;
recur(words, out, n + 1);
words[i] = temp;
}
}
}
The main thing to keep in mind is that you need to keep a state variable to decide the combination to print in each recursive call.
For example, the state variable could be a 3 digit number i.e. 123. And then map these digits with the words, for example, 1 is "MIKE", 2 is "AND", 3 is "IKE". So if the function is called with 123 then you would print "MIKEANDIKE", and then call again with next permutation of 123 which is 132 and so on.
I just mentioned one possible state variable variation. There could be countless way to declare a state variable. The main idea you can get from this is an idea of how you can approach to solve the problem.
Hope this helps! Let me know if don't understand anything. Happy coding!

Kattis - Secret Chamber

I'm required to solve the following problem for one of my classes: https://open.kattis.com/problems/secretchamber
My solution seems to work, but it's failing the third test case. I implemented every rule given by the problem description, and it solves the two sample test cases no problem. I'm at my wit's end, and I don't know what I'm doing wrong.
I'm not asking for anyone to do my homework by any means whatsoever, but any pointers on what I'm missing would be greatly appreciated.
import java.io.*;
import java.util.*;
class secretchamber
{
public static void main(String[] args)
{
Scanner stdin = new Scanner(System.in);
int numTranslations = stdin.nextInt();
int numPairs = stdin.nextInt();
stdin.nextLine();
ArrayList<Character> trans1 = new ArrayList<Character>(numTranslations);
ArrayList<Character> trans2 = new ArrayList<Character>(numTranslations);
for(int i = 0; i < numTranslations; i++)
{
String temp = stdin.nextLine();
trans1.add(temp.charAt(0));
trans2.add(temp.charAt(2));
}
for(int i = 0; i < numPairs; i++)
{
String temp = stdin.nextLine();
String[] pair = temp.split("\\s+");
char[] a = pair[0].toCharArray();
char[] b = pair[1].toCharArray();
if(translates(a, b, numTranslations, trans1, trans2))
{
System.out.println("yes");
}
else
{
System.out.println("no");
}
}
}
public static boolean translates(char[] a, char[] b, int numTranslations, ArrayList trans1, ArrayList trans2)
{
//false if strings are unequal in length
if(a.length != b.length)
{
return false;
}
//true if strings are the same
else if(a == b)
{
return true;
}
else
{
for(int i = 0; i < a.length; i++)
{
//if current characters are the same, continue
if(a[i] == b[i])
{
continue;
}
//if current index of a directly translates to index of b
else if(trans1.indexOf(a[i]) == trans2.indexOf(b[i]))
{
continue;
}
//if one or both of the characters do not exist within the list of translations
else if(!(trans1.contains(a[i]) && trans2.contains(b[i])))
{
return false;
}
else
{
continue;
}
}
}
return true;
}
}
Your understanding for the problem is worng. You need to read again this part in the problem.
Two words match if they have the same length and if each letter of the first word can be turned into the corresponding letter of the
second word by using the available translations zero or more times.
This input can make your output goes worng.
Input
2 1
a c
d b
aaa abc
Expected output
no
Your output
yes
Below is solution sketch for this problem.
I got it from icpc website.
It's happenstance that your code works on the sample cases. Check the it -> of translation in the provided example carefully. i doesn't directly translate to o, but it does directy translate to r, and r translates to o. You need to follow all translation paths step by step for each character and build a graph that lets you efficiently test whether a translation is possible.
Consider buiding a structure like HashMap<Character, Set<Character>> that maps each of the 26 letters to all of the possible characters it can translate to. For the provided example, o would map to {'r', 'o', 't', 'c', 'f', 'e'}. Repeat the same procedure for each of the provided translations.
Once you've built this data structure, it's a straightforward task of iterating over characters and performing lookups. a should have the same length as b and b[i] should be in the translation set for a[i], for all i.

Java Method for removing duplicates from char array

I have a char array filled by the user (arrayInput[]) with some characters, like {b, d, a, b, f, a, g, a, a, f}, and I need to create a method which returns a new char array with only the first occurrence of the character, but in the order of input. The book also says "A way to solve this problem is to create a boolean array to keep track of the characters to mantain!", but I can't imagine how the boolean array should work with the other arrays.
The main problem is that I can save in a boolean array if arrayInput contains a specific character, and even how many times, but only creating a very long ramified if-else into a for, like
if ((arrayOutput[i] == 'A') && (arrayControl[0] = false)) {
arrayControl[0] = true; }
where arrayOutput is the array I want to return from the method, arrayControl[0] is the value of 'A' in my boolean array I created into the method. A = 0, B = 1, ... Z = 25, a = 26, b = 27, ... 51 = z. For every single character, uppercase and lowercase, I created a place into the array, so I could check everything, but now I can't go any further. I don't know how to save the characters on arrayOutput, how to check if a character is already on arrayOutput and if it's already there, the array passes that specific character and go to the next one.
Also please remember I'm a newbie, so I know very little about Java. Please explain yourself the best you can. Thanks in advance!
This could work:
public static void main(String[] args) {
Main main = new Main();
char[] array = {'e','a','b','a','c','d','b','d','c','e'};
main.getCharArray(array);
}
private char[] getCharArray(char[] array) {
String _array = "";
for(int i = 0; i < array.length; i++) {
if(_array.indexOf(array[i]) == -1) // check if a char already exist, if not exist then return -1
_array = _array+array[i]; // add new char
}
return _array.toCharArray();
}
Output:
eabcd
boolean arr[26]; //considering only small letters arrive. otherwise take a larger array.
for( i=0;i<str.length;i++ )
arr[str[i]-'a']=true;
The ones at last after the loop are true are the actual character. (all duplicates eleminated).
To take into consideration the positions,
int arr[26];
//initialize all the array elemnts to 0
for( i=0;i<str.length();i++ )
if(i>=arr[str[i]-'a'])
arr[str[i]-'a']=i+1;
//Those greater than 0 are non-duplicated characters. Their poistion of first occurence= (arr[i]-1)
EDIT: I have last used java almost a year ago. The algorithm is shown properly. Sorry for my awkward java code.
This might help. Make a separate array and store only non-duplicate characters.
char[] removeDuplicates (char[] arrayInput) {
boolean exists[]=new boolean[26];
char arrayOutput[] = new char[26];
int ctr=0;
for(int i=0; i<26; i++) {
exists[i] = false;
}
for(int i=0; i<arrayInput.length; i++) {
if(!exists[arrayInput[i]-97]) {
exists[arrayInput[i]-97]=true;
arrayOutput[ctr++]=arrayInput[i];
}
}
return Arrays.copyOfRange(arrayOutput, 0, ctr);
}
If you consider using of collection framework then it would be much easier. Your array of char with duplicate is arrayInput. Now put each char from it to a HashSet like this -
HashSet<Character> uniqueCharSet = new HashSet<Character>();
for(char each : arrayInput){
uniqueCharSet.add(each);
}
Now the HashSet uniqueCharSet will contains only the unique characters from the char array arrayInput. Note here all element in uniqueCharSet are wrapper type - Character.
You can convert the HashSet uniqueCharSet to array of Character like this -
Object[] uniqueCharArray = uniqueCharSet.toArray();
And then you can use them like this -
for(Object each : uniqueCharArray){
Character c = (Character) each;
System.out.println(c);
}
Here's the method to achieve what you need:
public static void main(String[] args) {
char[] arr= {'A','B','C','A','B'};
HashSet<Character> hset=new HashSet<Character>();
for(int i=0;i<arr.length;i++) {
hset.add(arr[i]);
}
Object[] ObjChar=hset.toArray();
char[] resultArr = new char[ObjChar.length];
for(int j=0;j<ObjChar.length;j++) {
resultArr[j]=(char) ObjChar[j];
}
for(char eachChar: resultArr) {
System.out.println(eachChar);
}
}

Compare the index of 2 String arrays with different values Java

I have 2 parallel arrays: the first contains State Names, the second Capitals of the states.
I'm making a quiz that randomly generates a State then asks the user to enter the Capital of the state. Once the input is received I want to call a method to check if the index of the capital entered is the same as the index of the state it goes with.
ie: stateArray[0] = "New York" and capitalArray[0] = "Albany".
Check Answer Method
public static void checkAnswer(String[]stateArray, String capitalArray, String answer)
{
int index;
for (int i = 0; i < capitalArray.length; i++){
if(capitalArray[i].equalsIgnoreCase(answer)){
index = i;
}
}
if(capitalArray[index] == stateArray[index])
{
System.out.println("correct");
}
else
{
System.out.println("incorrect");
}
}
I know the second if statement is wrong. How can I compare the two arrays using the index where the users answer was found in the capitalArray?
boolean checkAnswer(String[] stateArray, String[] capitalArray, String displayedState, String answer) {
for (int i = 0; i < stateArray.length; i++) {
if (stateArray[i].equals(displayedState) && capitalArray[i].equals(answer)) {
return true;
}
}
return false;
}
Or something. The key is you need to pass in something to represent the state you displayed.
You need to keep track of the index that holds the State displayed to the user. For example, the way your code is written now gives the user the ability to get a right answer by giving a wrong answer. Take this example as explanation:
string[] stateArray = {"New York", "California"};
string[] capitalArray = {"Albany", "Sacramento"};
If you were to show "New York" as the question and the user happens to answer "Sacramento" your code would display correct.
You also need a case in which the answer does not match any of the capitals in the array. One way of doing this to implement in your code is to initiate the index to -1.
int index = -1;
Once you finish the for loop check if index is -1 and display "Your answers is not a valid State" or something along those lines.
Maybe use a HashMap, I am not completely familiar with Java it appears to be the similar to a Dictionary in Python. Dictionary object has great performance.
Since you know what state you asked about you should know its array index as well. As you see below both arrays are declared as class variables.
... class Quiz {
private String[] states = new String[50];
private String[] capitals = new String[50];
... method to fill both arrays with the correct data
public static void checkAnswer(int question, String answer)
{
if(capitalArray[question].equalsIgnoreCase(answer)){
{
System.out.println("correct");
}
else
{
System.out.println("incorrect");
}
}
}
It's better to have checkAnswer method's return type as Boolean, but I left it your way.
An alternate implementation in Java would be to use a Map instead of two arrays.
Map<String,String> stateCapitals = new HashMap<String,String>();
stateCaptitals.put("New York", "Albany");
then you can check the map with
public voic checkAnswer(String chosenState, String chosenCapital) {
if (stateCapitals.get(chosenState).equals(chosenCapital) {
System.out.println("you are correct!");
}
}
This does not do it with 2 parallel arrays, but it is a better implementation if your real concern is the type of data you mentioned, and not the arrays themselves.
Try this function it return array:-
public static String[] numSame (String[] list1, String[] list2)
{
int same = 0;
for (int i = 0; i <= list1.length-1; i++)
{
for(int j = 0; j <= list2.length-1; j++)
{
if (list1[i].equals(list2[j]))
{
same++;
break;
}
}
}
String [] array=new String[same];
int p=0;
for (int i = 0; i <= list1.length-1; i++)
{
for(int j = 0; j <= list2.length-1; j++)
{
if (list1[i].equals(list2[j]))
{
array[p]= list1[i]+"";
System.out.println("array[p] => "+array[p]);
p++;
break;
}
}
}
return array;
}

Reverse String Program

I have written a short String reverse program in C++. I decided to write it in Java, and so I did. However, once I completed writing the program, I encountered several errors that I have tried to fix but cannot fix. One of the errors was an ArrayOutOfBounds exception. Please help me fix the errors. The C++ program worked fine. Below is the Java code. Please note that I do not want to use inbuilt functions.
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
String word;
int i = 0;
boolean inp = true;
System.out.println("Enter one or more words to be reversed:");
word = scan.nextLine();
char wordArray[] = word.toCharArray();
while(wordArray[i]!='\0')
i++;
while(inp == true){
i--;
System.out.println(wordArray[i]);
if(i==0){
System.out.println();
break;
}
}
}
}
There is no null-terminating character in Java strings; they have a length() method you should use to determine length.
Also, the while loop would be more idiomatic as:
while (true) {
...
}
Or as a simple for loop.
This is another possibility, perhaps simpler:
public String reverse(String str) {
char[] chars = str.toCharArray();
int n = chars.length;
for (int i = 0; i < n/2; i++) {
char tmp = chars[i];
chars[i] = chars[n-i-1];
chars[n-i-1] = tmp;
}
return new String(chars);
}
And although you mentioned that you don't want to use built-in functions, the most idiomatic way would be this:
public String reverse(String str) {
return new StringBuilder(str).reverse().toString();
}
strings in java are not necessarily null terminated, you should use String.length() method to find out how long it is.
Java Strings are not zero-terminated, thus the byte array created from string isn't either. You used a loop to determine the length of your array, but that loop doesn't find a byte with value 0, so it goes over the range. Use word.length() instead.
The second thing: You used System.out.println to print the character - that inserts a linebreak after each character. Is this intended?

Categories

Resources