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.
Related
I've wrote a method/function in Java which returns the result of a given basic equation. This equation will be given as a String and I think I got this method working but don't know why I need this one line of Code because this should work without it. After trying for more than an hour to solve it I gave up and hope you can give me an aswer.
Here the Code:
public static double format(String s) {
char[] c = s.toCharArray();
if(s.contains("(")) {
int openbrackets = 0;
for (int i = 0; i < s.length() - 2; i++) {
if (c[i] == '(') openbrackets++;
else if (c[i] == ')') {
openbrackets--;
if(openbrackets == 0) {
s = s.replace(s.substring(s.indexOf('('), i+1), ""+(format(s.substring(s.indexOf('(')+1, i))));
break;
}
}
}
}
if (s.contains("(")) { // String can still contains brackets
s = "" + format(s);
}
c = s.toCharArray();
for(int i = c.length-1; i >= 0; i--) {
if(c[i] == '+') {
return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
} else if(c[i] == '-') {
return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
}
}
for(int i = s.length()-1; i > 0; i--) {
if(c[i] == '*') {
return format(s.substring(0, i)) * Double.parseDouble(s.substring(i+1, s.length()));
} else if (c[i] == '/') {
return format(s.substring(0, i)) / Double.parseDouble(s.substring(i+1, s.length()));
}
}
return s.equals("") ? 0 : Double.parseDouble(s); // I don't understand why I need to do this line
}
Description:
I don't know why I need this s.equals("") ? : because the String never should be empty however when I run it with this equation ((23)+(23-23-432-35-1-2-4231+2312+12323-(-3))*3/2) for example I get an error without it.
I need the parser to convert config Strings into Numbers for example when it comes to screenresolution. I know I can also use Libraries but I want to try these things by myself.
PS: Dont hate me just because I don't use libraries. I really tried to figure it out and I have fun doing it. I would just like to know why I have to write this little Codeline as I don't figure it out...
Edit: Error was a NumberFormatException as the Parsing got an empty String... Got my error now also the OverflowException which was mentioned in the comments...
EDIT: To everyone who MIGHT use something like this in the future:
Here the Code which actually works:
public static double format(String s) {
s = s.replace(" ", "");
s = s.replace("\t", "");
char[] c = s.toCharArray();
if(s.contains("(")) {
int openbrackets = 0;
for (int i = 0; i < s.length(); i++) {
if (c[i] == '(') openbrackets++;
else if (c[i] == ')') {
openbrackets--;
if(openbrackets == 0) {
s = s.replace(s.substring(s.indexOf('('), i+1), ""+(format(s.substring(s.indexOf('(')+1, i))));
break;
}
}
}
}
if (s.contains("(")) s = "" + format(s);
c = s.toCharArray();
for(int i = c.length-1; i > 0; i--) {
if(c[i] == '+') {
return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
} else if(c[i] == '-') {
return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
}
}
for(int i = s.length()-1; i > 0; i--) {
if(c[i] == '*') {
return format(s.substring(0, i)) * Double.parseDouble(s.substring(i+1, s.length()));
} else if (c[i] == '/') {
return format(s.substring(0, i)) / Double.parseDouble(s.substring(i+1, s.length()));
}
}
return s.equals("") ? 0 : Double.parseDouble(s);
}
I'm fairly sure this is at least one location in your code where you pass a 0 length string to your format function:
c = s.toCharArray();
for(int i = c.length-1; i >= 0; i--) {
if(c[i] == '+') {
return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
} else if(c[i] == '-') {
return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
}
}
Your loop counter in (int i = c.length-1; i >= 0; i--) will get decremented until it is 0 in value if there are no + or - values in the input string.
Then you call format(s.substring(0, i)) where i = 0 so I think this is one place where you will be passing a zero length/empty string to your function.
Please use a debugger and step through your code - not only would it teach you a valuable skill it would also probably give you the answer you're looking for.
I wanna to solve my Homework about calculating number value of String in Java like "-3.1+0.12*0.0023-34.1/2.1"
I have limitations to use only Arrays and Strings and not use recursive functions (as first year student)
What I try?
I am trying to solve it by parsing string char by char.
I try this method only for + and - :
public static double CalcPlusMinus(String s) {
double A[] = new double[10000];
if ((s.charAt(0) != '+') && (s.charAt(0) != '-'))
s = '+' + s;
int i = 0, j = 0;
while (i < s.length()) {
int flag = 1;
if (s.charAt(i) == '-')
flag = -1;
i++;
double m = 0;
int end = 0;
if ((s.charAt(i) >= '0') && (s.charAt(i) <= '9'))
while ((s.charAt(i) >= '0') && (s.charAt(i) <= '9')) {
m = m * 10 + (s.charAt(i) - '0');
i++;
if (i >= s.length()) {
end = 1;
break;
}
}
if (end == 0)
if (s.charAt(i) == '.') {
i++;
double x = 10;
while ((s.charAt(i) >= '0') && (s.charAt(i) <= '9')) {
m = m + ((s.charAt(i) - '0') / x);
x *= 10;
i++;
if (i >= s.length())
break;
}
}
A[j++] = m * flag;
}
A[A.length - 1] = j;
for (int m = (int) A[A.length - 1] - 1; m > 0; m--) {
A[m - 1] = A[m] + A[m - 1];
}
return A[0];
}
I am trying to add * and / to this method
But my main question is : how can I control a lot of if-then-else in my code?
Is there any formal way to control a lot of ifs in the code?
I know flowcharts, but the flowchart turn to a very big picture too!!
You should have 3 separate steps:
parsing/tokenization - spiting "-3.1+0.12*0.0023-34.1/2.1" into:
"-" "3.1" "+" "0.12" "*" "0.0023" "-" "34.1" "/" "2.1"
convert to Reverse Polish notation, using array as a stack
calculating the value of expression
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);
I'm trying to create a loop which only returns letters. In my code, I get symbols that I don't want. How do I fix my loop so that when my integer is +3, it only gives me letters?
public static String caesarDecrypt(String encoded, int shift){
String decrypted = "";
for (int i = 0; i < encoded.length(); i++) {
char t = encoded.charAt(i);
if ((t <= 'a') && (t >= 'z')) {
t -= shift;
}
if (t > 'z') {
t += 26;
} else if ((t >= 'A') && (t <= 'Z')) {
t -= shift;
if (t > 'Z')
t += 26;
} else {
}
decrypted = decrypted + t;
}
}
You are subtracting the shift value from the letters. Therefore, the new letter can never be > 'z'. You should check if the it is < 'a' (or 'A', respectively).
StringBuilder decrypted = new StringBuilder(encoded.length());
for (int i = 0; i < encoded.length(); i++)
{
char t = encoded.charAt(i);
if ((t >= 'a') && (t <= 'z'))
{
t -= shift;
while (t < 'a')
{
t += 26;
}
}
else if ((t >= 'A') && (t <= 'Z'))
{
t -= shift;
while (t < 'A')
{
t += 26;
}
}
decrypted.append(t);
}
return decrypted.toString();
Also, you shouldn't be using String concatenation to generate the result. Learn about StringBuilder instead.
EDIT: To make sure the new letter is in the range 'a' .. 'z' for an arbitrary (positive) shift, you should use while instead of if.
I am not giving you exact code. But I can help you in logic:
Check whether you are reaching end points (a, A, z, Z) due to the shift.
If you exceed the end points either way, then compute the distance between end points and shifted t. Add/subtract/modulus (based on the end point) this distance to the other endpoint to get the exact letter.
Something like this? (Warning, untested)
public static String caesarDecrypt(String encoded, int shift) {
String decrypted = "";
for (int i = 0; i < encoded.length(); i++) {
char t = encoded.charAt(i).ToUpper();
decrypted = decrypted + decode(t, shift);
}
}
// call with uppercase ASCII letters, and a positive shift
function decode(char n, int shift)
{
if ((n < 'A') || (n > 'Z')) return ('-');
var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var s = str.charAt(((n - 'A') + shift)%26);
return(s);
}
As you are naming your method caesarDecrypt (I assume you mean encrypt), I think you want a shift in the alphabet including wrapping around.
This code will do that for you:
public class Snippet {
public static void main(String[] args) {
System.out.println(caesarShift("This is a Fizzy test.", 5));
System.out.println(caesarShift("Ymnx nx f Kneed yjxy.", -5));
}
public static String caesarShift(String input, int shift) {
// making sure that shift is positive so that modulo works correctly
while (shift < 0)
shift += 26;
int l = input.length();
StringBuffer output = new StringBuffer();
for (int i = 0; i < l; i++) {
char c = input.charAt(i);
char newLetter = c;
if (c >= 'a' && c <= 'z') { // lowercase
newLetter = (char) ((c - 'a' + shift) % 26 + 'a'); // shift, wrap it and convert it back to char
} else if (c >= 'A' && c <= 'Z') { // uppercase
newLetter = (char) ((c - 'A' + shift) % 26 + 'A'); // shift, wrap it and convert it back to char
}
output.append(newLetter);
}
return output.toString();
}
}
This will handle lowercase and uppercase letters. Everything else will be left as it is (like spaces, punctuations, etc).
Please take some time to look at this code to understand how it works. I have put some comments to make it clearer. From your code I think you were a bit confused, so it is important that you understand this code very well. If you have questions, feel free to ask them.
This code
String start = "abcdefghijklmnopqrstuvwxyz";
String encrypted = caesarShift(start, 3);
String decrypted = caesarShift(encrypted, -3);
System.out.println("Start : " + start);
System.out.println("Encrypted : " + encrypted);
System.out.println("Decrypted : " + decrypted);
will give this result
Start : abcdefghijklmnopqrstuvwxyz
Encrypted : defghijklmnopqrstuvwxyzabc
Decrypted : abcdefghijklmnopqrstuvwxyz
for (int i = 0; i < str.length(); i ++) // Checks every position of array
{
arr[i] = str.charAt(i); // Ignore this, not needed
if (arr[i] != ',' || arr[i] != '.' || arr[i] != '$') // Checks every position of array to see if any character equals a comma, decimal point, or a dollar sign
{
// Ignore below
/*
valueString = String.valueOf(value);
numOfAsterisks = arr.length - valueString.length();
for (int asterisk = 0; asterisk <= numOfAsterisks; asterisk ++)
{
System.out.print("*");
}
System.out.println((int)value);
*/
}
}
Here, what I want to do is to check an array of characters and see if the array contains a comma, a decimal point, or a dollar sign. If the array does not contain any of these characters, then the commented-out portion (where it says "Ignore below") will be executed. The only problem I have here is that because if (arr[i] != ',' || arr[i] != '.' || arr[i] != '$') is under the outside for loop, the commented-out part is executed multiple times. I need the code to execute only once, but still check each position of the array.
If I understand your question correctly, what you actually want is something like this:
boolean found = false;
for(int i = 0; i < str.length; i++) {
char c = str.charAt(i);
if(c == ',' || c == '.' || c == '$') {
found = true;
break;
}
}
if(!found) {
/* Your commented-out code */
}
Note that this can also be formulated as such:
skip: {
for(int i = 0; i < str.length; i++) {
char c = str.charAt(i);
if(c == ',' || c == '.' || c == '$')
break skip;
}
/* Your commented out code goes here. */
}
Choose for yourself which you like more. :)