for my compsci assignment we're supposed to take a string given to us with integers and letters in it, then create a method that takes that string and converts it into an integer array with the integers in it. For some reason my method is not adding ints to the array, I'm not sure why.
For the LETTERS given in the string, we're supposed to discard them, so we have an array with ONLY int values; ex. input: abs3131afas312 the array would have {3131,312}
This is the link to the assignment.
Here's my method:
public static int[] intParse(String a){
int[] array1 = new int[a.length()];
int b = 0;
for(int i = 0; i < a.length(); ++i)
{
int g = a.charAt(i);
if(g == 1 || g == 2 || g == 3 || g == 4 || g == 5 || g == 6 || g == 7 || g == 8 || g == 9 || g == 0)
{
String c;
for(int j = i; j < a.length(); ++j)
{
int k = a.charAt(j);
if(k != 1 && k != 2 && k != 3 && k != 4 && k != 5 && k != 6 && k != 7 && k != 8 && k != 9 && k != 0)
{
c = a.substring(j,k-1);
array1[b] += Integer.parseInt(c);
b++;
j = (a.length());
i = a.charAt(j);
}
else
{
c = a.substring(j,a.length());
array1[b] = Integer.parseInt(c);
j = a.length();
}
}
}
}
return array1;
}
Rather than comparing your characters to integers and using Integer.parseInt, you should be using the following very useful utility methods:
Character.isDigit(int codepoint)
Character.getNumericValue(int codepoint)
Also, your logic seems a little sketchy. When k is a digit code point, you are trying to parse the entire rest of the string. That doesn't seem consistent with what you're trying to do with the outer loop.
First of all, a is a string, and contains ASCII characters not integers. Character '1' is not equal to the integer 1. It is equal to the ASCII value of '1' which happens to be 49.
So first thing you should do is change that long if condition to:
char c = a.charAt(i);
if (c >= '0' && c <='9')
{
...
}
What you should do then is keep a string (a new string each time you encounter a non-numeric character and then a numeric character, and keep appending c to it until the character you find is non-numeric.
Then you can simply do Integer.parseInt(yourString) to get the number in an integer.
a fix for you:
char g = a.charAt(i);
if(g == '1' || g == '2' || g == '3' || g == '4' || g == '5' || g == '6' || g == '7' || g == '8' || g == '9' || g == '0') {
or much nicer:
char g = a.charAt(i);
if(g >= '0' && g <= '9') {
Your other if needs to be fixed, too
char k = a.charAt(j);
if(k < '0' || k > '9') {
You might prefer this approach:
Scanner sc = new Scanner("abs3131afas312");
String match;
while ((match = sc.findInLine("(\\d+)"))!=null) {
// instead of printing it, put it in your array
// or a list (and then convert to array)
System.out.println(Integer.parseInt(match));
}
sc.close();
Output:
3131
312
Related
I want to find vowels positions in the string. How can I make shorter this code?
I tried contains and indexOf method but couldn't do it.
String inputStr = "Merhaba";
ArrayList<Character> vowelsBin = new ArrayList<Character>(Arrays.asList('a', 'e', 'i', 'o', 'u'));
ArrayList<Integer> vowelsPos = new ArrayList<Integer>();
for (int inputPos = 0; inputPos < inputStr.length(); inputPos = inputPos + 1)
for (int vowelPos = 0; vowelPos < vowelsBin.size(); vowelPos = vowelPos + 1)
if (inputStr.charAt(inputPos) == vowelsBin.get(vowelPos)) vowelsPos.add(inputPos);
return vowelsPos;
I assume you want to get m2rh5b7 from your input string Merhaba based on your code, then the below works fine,
String input = "Merhaba";
StringBuilder output = new StringBuilder();
for(int i = 0; i < input.length(); i++){
char c = input.toLowerCase().charAt(i);
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'){
output.append(i+1);
} else {
output.append(c);
}
}
System.out.println(output); // prints --> m2rh5b7
Or if you want just position of the vowels position only, the below is fine,
String input = "Merhaba";
for(int i = 0; i < input.length(); i++){
char c = input.toLowerCase().charAt(i);
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'){
System.out.println(i);
}
}
you can use regex also, please refer the above from Alias.
Here is the code I wrote in Java to count vowels (a, e, i, o, u, y) in n strings:
import java.util.*;
import java.io.*;
public class VowelCount {
public static void main(String[] args) {
Scanner x = new Scanner(System.in);
int n = x.nextInt();
int[] count = new int[n];
for(int i = 0; i < n; i++) {
if(x.hasNextLine()) {
String str = new String(x.nextLine());
int counter = 0;
for(int j = 0; j < str.length(); j++) {
char ch = str.charAt(j);
if(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U' || ch == 'y' || ch == 'Y') {
counter += 1;
}
}
count[i] = counter;
}
}
for(int k = 0; k < n; k++) {
System.out.print(count[k] + " ");
}
}
}
If I insert 10 strings like:
(hello, hi, string, int, double, boo, ad, ok, def, rep)
it should return
2 1 1 1 3 2 1 1 1 1
but what it returns is
0 2 1 1 1 3 2 1 1 1
so it count the first one as the second and doesn't count the last one (in fact right after writing "def" in the console it runs the code and prints the solution in console.
Can you help me figure it out where I am wrong? It would be really appreciated, thanks!
This looks like standard hackerrank format. I believe most of the templates include code to read the data - if one problem doesn't, just copy code from one that does.
I'm guess the problem here is that nextInt does not read the line ending. The first nextLine just reads the newline after the count.
int n = x.nextInt();
int[] count = new int[n];
for(int i = 0; i < n; i++) {
if(x.hasNextLine()) {
String str = new String(x.nextLine());
The method .nextInt() doesn't finish to read all the line, so your first call to x.nextLine() catch the space after the int.
Just add a line after : x.nextLine();
int n = x.nextInt();
int[] count = new int[n];
x.nextLine();
Here's my code that I've written :
public String binary(String s)
{
String[] a = {
"0000","0001","0010","0011","0100","0101","0110","0111",
"1000","1001","1010","1011","1100","1101","1110","1111"
};
String k = "";
for(int i = 0; i <= s.length() - 1; i++)
{
if (s.charAt(i) == 'a') { k += a[10]; }
else if (s.charAt(i) == 'b') { k += a[11]; }
else if (s.charAt(i) == 'c') { k += a[12]; }
else if (s.charAt(i) == 'd') { k += a[13]; }
else if (s.charAt(i) == 'e') { k += a[14]; }
else if (s.charAt(i) == 'f') { k += a[15]; }
else { k += a[i]; }
}
return k;
}
I am getting output as a[0-9] = 0000. How can I fix this? What am I doing wrong?
The problem is with use of a[i]. It is a logical error. Because i is loop variable which indicates the current index in s String. But you are using it to indexing it in variable a. So, i variable is use incorrectly here.
Following is corrected (and a bit optimized) code. See it working here:
public class HexaDecimal
{
public String binary(String s)
{
String[] a= {"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
String k="";
for(int i=0;i<s.length();i++)
{
char ch = Character.toUpperCase(s.charAt(i));
if(ch>='A' && ch <= 'F') k+= a[ch - 'A' + 10];
else k+= a[ch - '0'];
}
return k;
}
}
Replace k+=a[i]; with k+=a[s.charAt(i) - '0'];
You're using your string index loop variable as an index into a rather than the character at that location in the string.
You need to do - '0' to convert from unicode codepoint to the value it represents as an ASCII digit (which I assume you want to use here)
Your last else does the incorrect calculation. It does not take into consideration what is inputted, only the position. You want it to be
else {
k += a[s.charAt(i) - '0'];
}
There are easier ways to get the binary representation of hexadecimals, and you probably also want to check the input that it does not contain anything else than 0-9 or a-f.
You can change the for loop to this:
for(int i=0; i < s.length(); i++)
{
char c = s.charAt(i);
if (c >= '0' && c <= '9') k += a[c - '0'];
else if (c >= 'a' && c <= 'f') k += a[c - 'a' + 10];
else if (c >= 'A' && c <= 'F') k += a[c - 'A' + 10];
else throw new InvalidArgumentException(s);
}
This is a lot simpler and self-explanatory, at least in my opinion. Handles digits, uppercase and lowercase letters, and fails in an expected way on bad input.
I want to write a function to check if a given string in roman presentation is correct or not. They are a lot of cases of non allowed combinations : (I assume that the given string will represent a number between 1 and 3999)
We can't have the same character more than three times in a row : ex : IIII is false.
Some combinations are not allowed : DD is false ('D' + 'D' = 500 + 500 = 1000 which is M
We can't substract a character and add the same character just after : for example IXI is not correct event if IX is 9, it's not equal to 9 + 1
The most significant digits has to be at the beginning not at the middle or at the end. Ex : XM (for 1010) is false while MX is the correct one.
etc...
So, my idea was that rather than checking for the non allowed combinations, I will write ALL the possible allowed combinations and each time we meet a combination which is not among them, we will return false. That was my idea. The inconvenient is that my final function was very long and not really easy to understand.
For example, I wrote first a function to check for the thousands (if they exist of course), the function then returns the indexes that I will use to substring the current string to move to the next part (which will be hundreds in that case) :
private static int isThousandsValid(String str){
int len = str.length();
char a1 = str.charAt(0);
char a2 = (len >= 2)? str.charAt(1) : ' ';
char a3 = (len >= 3)? str.charAt(2) : ' ';
if (a1 == 'M' && a2 == 'M' && a3 == 'M') //if we met that combinatin
return 3; //we have to move after 3 digits to meet the beginning
//of the hundred digits
else if (a1 == 'M' && a2 == 'M') //same raisoning for other combinations
return 2;
else if (a1 == 'M')
return 1;
else if (a1 == 'D' || a1 == 'C' || a1 == 'L' || a1 == 'X' || a1 == 'V' || a1 == 'I' )
return 0;
else return -1;
}
Then, I wrote the same thing for hundreds, tens and units. Example for hundreds :
private static int isHundredsValid(String str){
if (str.isEmpty()) return 0;
int len = str.length();
char a1 = str.charAt(0);
char a2 = (len >= 2)? str.charAt(1) : ' ';
char a3 = (len >= 3)? str.charAt(2) : ' ';
char a4 = (len >= 4)? str.charAt(3) : ' ';
if (a1 == 'C' && a2 == 'M')
return 2;
else if (a1 == 'D' && a2 == 'C' && a3 == 'C' && a4 == 'C')
return 4;
else if (a1 == 'D' && a2 == 'C' && a3 == 'C')
return 3;
else if (a1 == 'D' && a2 == 'C')
return 2;
else if (a1 == 'D')
return 1;
else if (a1 == 'C' && a2 == 'D')
return 2;
else if (a1 == 'C' && a2 == 'C' && a3 == 'C')
return 3;
else if (a1 == 'C' && a2 == 'C')
return 2;
else if (a1 == 'C')
return 1;
else if (a1 == 'L' || a1 == 'X' || a1 == 'V' || a1 == 'I' )
return 0;
else return -1;
}
Then, in my final function, I write this :
public static boolean isValidRoman(String str){
str = str.trim(); //remove spaces
if (str.isEmpty()) return false;
int index1 = isThousandsValid(str);
String str1 = mySubstring(str, index1);
int index2 = isHundredsValid(str1);
String str2 = mySubstring(str1, index2);
int index3 = isTensValid(str2);
String str3 = mySubstring(str2, index3);
int index4 = isUnitsValid(str3);
String str4 = mySubstring(str3, index4);
if (str1.isEmpty() || str2.isEmpty() || str3.isEmpty())
return true;
if (index1 == -1 || index2 ==-1 || index3 == -1 || index4 == -1)
return false;
return str4.isEmpty(); //if we still have ANOTHER character after it terminates
}
Finally "mySubstring" is just a simple function that I used to refactor and clear my code :
private static String mySubstring(String str, int index){
if (index == -1 ) return str;
else
return str.substring(index);
}
I have please two main questions :
Does this function seem correct for you? I had tested in many examples but I'm not really sure (I can't test all the 3999 possible combinations...)
Is it possible to improve it? Just to make it cleaner or more readable?
Is there any easier way to check for the validity of roman number rather than write all those cases??
I would go for the short and crazy solution and match the string using a regular expression:
public boolean isRoman(String s)
{
return !s.isEmpty()
&& s.matches("M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})");
}
I want to write a program which receive a string value and print the decimal number.
In addition, if the string value is not 1 or 0, I need to print a message.
I wrote this code but it is always getting inside the if command.
I Would appreciate your support!
Thank you
import java.util.Random;
public class Decimal {
public static void main(String[] args) {
String input = (args[0]);
int sum = 0;
for (int i = 0; i <= input.length(); i++) {
if (!(input.charAt(i) == '0') || (input.charAt(i) == '1')) {
System.out.println("wrong string");
break;
}
char a = input.charAt(i);
if (a == '1') {
sum |= 0x01;
}
sum <<= 1;
sum >>= 1;
System.out.println(sum);
}
}
}
The ! (not) operator of the if statement only applies to the first part:
if ( ! (input.charAt(i) == '0')
||
(input.charAt(i) == '1')
) {
So that is the same as:
if ((input.charAt(i) != '0') || (input.charAt(i) == '1')) {
When you actually meant to do:
if (input.charAt(i) != '0' && input.charAt(i) != '1') {
It's a good thing though, because once that works, you're going to get an IndexOutOfBoundsException when i == input.length(). Change the loop to:
for (int i = 0; i < input.length(); i++) {
And for performance, move variable a up and use it in that first if statement. Rename to c or ch is more descriptive/common.
Doing both sum <<= 1 and sum >>= 1 leaves you where you started. Is that what you wanted? You should also do the left-shift before setting the right-most bit.
Applying all that, I believe you meant to do this:
String input = args[0];
int sum = 0;
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c != '0' && c != '1') {
System.out.println("wrong string");
break;
}
sum <<= 1;
if (c == '1')
sum |= 1;
}
System.out.println(sum);