I am trying to create a method that converts Decimal to Binary. Here is what I wrote so far (which is not working properly):
public static String D2B(int decimal){
String binaryValue="";
for (int tempDecimal=decimal;0==tempDecimal;tempDecimal/=2){
binaryValue=tempDecimal%2+binaryValue;
}
return binaryValue;
}
public static void main(String[]args){
int myValue=127;
System.out.println(D2B(myValue));
}
I think the condition in your loop is incorrect:
for(int tempDecimal=decimal;0==tempDecimal;tempDecimal/=2)
Note that this loops while tempDecimal is equal to 0, which means that the loop should not loop at all for nonzero inputs and will loop forever for zero inputs. Try rewriting it as
for(int tempDecimal = decimal; 0 != tempDecimal; tempDecimal /= 2)
Also, watch out for 0 as an input and for negative numbers as inputs; they won't come out correctly with your current approach.
A few other minor nits:
I strongly suggest indenting your code correctly and putting spaces in-between the operators for readability. It makes the code much easier to read, and I think you would have spotted the bug more easily had you had more spaces.
There's no reason to create a second variable tempDecimal in this function. Java parameters are passed by value, so changes you make to the argument won't show up in the caller. Since you're not using the decimal value anywhere else, the extra variable is superfluous.
Hope this helps!
Related
I'm trying the solve this hacker earth problem https://www.hackerearth.com/practice/basic-programming/input-output/basics-of-input-output/practice-problems/algorithm/anagrams-651/description/
I have tried searching through the internet but couldn't find the ideal solution to solve my problem
This is my code:
String a = new String();
String b = new String();
a = sc.nextLine();
b = sc.nextLine();
int t = sc.nextInt();
int check = 0;
int againCheck =0;
for (int k =0; k<t; k++)
{
for (int i =0; i<a.length(); i++)
{
char ch = a.charAt(i);
for (int j =0; j<b.length(); j++)
{
check =0;
if (ch != b.charAt(j))
{
check=1;
}
}
againCheck += check;
}
}
System.out.println(againCheck*againCheck);
I expect the output to be 4, but it is showing the "NZEC" error
Can anyone help me, please?
The requirements state1 that the input is a number (N) followed by 2 x N lines. Your code is reading two strings followed by a number. It is probably throwing an InputMismatchException when it attempts to parse the 3rd line of input as a number.
Hints:
It pays to read the requirements carefully.
Read this article on CodeChef about how to debug a NZEC: https://discuss.codechef.com/t/tutorial-how-to-debug-an-nzec-error/11221. It explains techniques such as catching exceptions in your code and printing out a Java stacktrace so that you can see what is going wrong.
1 - Admittedly, the requirements are not crystal clear. But in the sample input the first line is a number.
As I've written in other answers as well, it is best to write your code like this when submitting on sites:
def myFunction():
try:
#MY LOGIC HERE
except Exception as E:
print("ERROR Occurred : {}".format(E))
This will clearly show you what error you are facing in each test case. For a site like hacker earth, that has several input problems in various test cases, this is a must.
Coming to your question, NZEC stands for : NON ZERO EXIT CODE
This could mean any and everything from input error to server earthquake.
Regardless of hacker-whatsoever.com I am going to give two useful things:
An easier algorithm, so you can code it yourself, becuase your algorithm will not work as you expect;
A Java 8+ solution with totally a different algorithm, more complex but more efficient.
SIMPLE ALGORITM
In you solution you have a tipical double for that you use to check for if every char in a is also in b. That part is good but the rest is discardable. Try to implement this:
For each character of a find the first occurence of that character in b
If there is a match, remove that character from a and b.
The number of remaining characters in both strings is the number of deletes you have to perform to them to transform them to strings that have the same characters, aka anagrams. So, return the sum of the lenght of a and b.
NOTE: It is important that you keep track of what you already encountered: with your approach you would have counted the same character several times!
As you can see it's just pseudo code, of a naive algorithm. It's just to give you a hint to help you with your studying. In fact this algorithm has a max complexity of O(n^2) (because of the nested loop), which is generally bad. Now, a better solution.
BETTER SOLUTION
My algorithm is just O(n). It works this way:
I build a map. (If you don't know what is it, to put it simple it's a data structure to store couples "key-value".) In this case the keys are characters, and the values are integer counters binded to the respective character.
Everytime a character is found in a its counter increases by 1;
Everytime a character is found in b its counter decreases by 1;
Now every counter represents the diffences between number of times its character is present in a and b. So, the sum of the absolute values of the counters is the solution!
To implement it actually add an entry to map whenever I find a character for the first time, instead of pre-costructing a map with the whole alphabet. I also abused with lambda expressions, so to give you a very different sight.
Here's the code:
import java.util.HashMap;
public class HackerEarthProblemSolver {
private static final String a = //your input string
b = //your input string
static int sum = 0; //the result, must be static because lambda
public static void main (String[] args){
HashMap<Character,Integer> map = new HashMap<>(); //creating the map
for (char c: a.toCharArray()){ //for each character in a
map.computeIfPresent(c, (k,i) -> i+1); //+1 to its counter
map.computeIfAbsent(c , k -> 1); //initialize its counter to 1 (0+1)
}
for (char c: b.toCharArray()){ //for each character in b
map.computeIfPresent(c, (k,i) -> i-1); //-1 to its counter
map.computeIfAbsent(c , k -> -1); //initialize its counter to -1 (0-1)
}
map.forEach((k,i) -> sum += Math.abs(i) ); //summing the absolute values of the counters
System.out.println(sum)
}
}
Basically both solutions just counts how many letters the two strings have in common, but with different approach.
Hope I helped!
So i am using string.split because i need to take certain parts of a string and then print the first part. The part size may vary so I can't use substring or a math formula. I am attempting to store everything I need in the string array to then selectively print what I need based on the position, this much I can control. However, I am not sure what to do because I know when I do a split, it takes the two parts and stores them in the array. However, there is one case where I need that value in the array untouched. I'm afraid if I do
format[0] = rename
That it will overwrite that value and mess up the entire array. My question is how do I assign a position to this value when I don't know what the position of the others will be? Do I need to preemptively assign it a value or give it the last possible value in the array? I have attached a segment of the code that deals with my question. The only thing I can add is that this is in a bigger loop and rename's value changes every iteration. Don't pay to much attention to the comments, those are more of reminders for me as to what to do rather than what the code is suppose to do. Any pointers, tips, help is greatly appreciated.
String format[];
rename = workbook.getSheet(sheet).getCell(column,row).getContents();
for(int i = 0; i < rename.length(); i++) {
//may need to add[i] so it has somewhere to go and store
if(rename.charAt(i) == '/') {
format = rename.split("/");
}
else if(rename.charAt(i) == '.') {
if(rename.charAt(0) == 0) {
//just put that value in the array
format = rename;
} else {
//round it to the tenths place and then put it into the array
format = rename.split("\\.");
}
} else if(rename.charAt(i) == '%') {
//space between number and percentage
format = rename.split(" ");
}
}
Whenever you assign a variable it gets overwritten
format[0] = rename
Will overwrite the first index of this array of Strings.
In your example, the 'format' array is being overwritten with each iteration of the for loop. After the loop has been completed 'format' will contain only the values for the most recent split.
I would suggest looking into using an ArrayList, they are much easier to manage than a traditional array and you can simply just iterate through the split values and append them at the end.
I am doing an assignment which asks me check the given phone number whether it matches the pattern(the pattern is ddd-ddd-dddd) and the numbers are within 0 to 9. I want to use for loop and substring method, but I have no idea how to use them. This code is what I've done so far.
public static boolean phoneNum(String s){
boolean a = false;
boolean b = false;
String phone = s.substring(1,4)+s.substring(5,8)+s.substring(9);
for(int i =0; i<phone.length(); i++){
y = Character.isDigit(s1.charAt(i));
}
if(s.charAt(4)=='-' && s.charAt(8)=='-' && b==true){
a = true;
return a;
}
return a;
}
If I can add for loop, where should it be?
You are asking how to improve the quality of this code, so let's give some ideas:
change its name to meet java conventions, like isValidPhoneNumber()
you don't need to "carry forward" the results of a previous check. Your method should simply return false immediately whenever it finds a condition to be violated. If all tests pass, you then simply return true in the end.
In other words: what makes your code hard to read and overly complicated are those single character named boolean variables. They mainly add confusion. And keep in mind that your code is ignoring that y variable for example. And even if y is just a typo that could still be simplified.
And to make that clear: avoid using names like a or b. These names mean nothing. They don't tell the reader anything about the purpose of that variable.
So I'm making a fraction calculator and I have one last part to figure out. For calculations that involve multiplying by 0, the final answer must always be 0. Due to my code I always end up with something like 0/1 or 0/5, so it always has a denominator. I want to return the answer without that denominator, but I'm not sure how to write my if statement. Here's my attempt at trying to print the 0 without the denominator.
if (reducedAnswer.charAt(0) == 0) {
return reducedAnswer.substring(0, 1);
}
I'm not quite sure how to modify that if statement to check if the first character of the answer is 0 so I can remove the unwanted parts. Any ideas?
You need a char literal, change
if (reducedAnswer.charAt(0) == 0) {
to
if (reducedAnswer.charAt(0) == '0') {
or use String.startsWith like
if (reducedAnswer.startsWith("0")) {
I have to trim (including whitespaces within the string) all the strings in a list. I have written a method to do this trim using regex. I am using strArray[i] = trimString(strArray[i]); instead of using an enhanced for loop. I assume since string is immutable this way of assigning back to the same array element is correct. Am I right?
public void trimStringArray(String[] strArray){
if(strArray!= null && strArray.length > 0){
for(int i=0;i<strArray.length;i++){
strArray[i] = trimString(strArray[i]);
}
}
}
Yes, that's fine, and you wouldn't be able to use the enhanced for loop. However, you can simplify your code by getting rid of the length > 0 check - there's no harm in it executing the loop 0 times... and personally I would usually expect the parameter to such a method to be non-null anyway, leading to code like this:
public void trimStringArray(String[] strArray) {
Preconditions.checkNotNull(strArray);
for(int i = 0; i < strArray.length; i++) {
strArray[i] = trimString(strArray[i]);
}
}
(Preconditions.checkNotNull comes from Guava in this case.)
You could leave it accepting null - but do you really have many situations where it's valid to have a null array, but you want to trim everything if it's not?
As a readability thing, I'd also encourage you to include a bit more whitespace - it's definitely a personal preference, but I know I find code with no spaces, such as this, harder to read:
for(int i=0;i<strArray.length;i++){
Yes, your code is correct.
Note that the strArray.length > 0 check is redundant: the loop condition will automatically take care of the case when strArray has zero length.
Yes, it is ok to do. I would add add final in method signature. By adding final you can make sure mistakenly you are not re-assigning references (added safety).
public void trimStringArray(final String[] strArray){