This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Write a program which checks an array of String contains valid numbers.If the string contains ".", convert it to Double, otherwise convert it to an Integer.Input should be array of string { "10.20", "123456", "12.invalid"}.
My problem is that 123456 is getting changed to double.I have to change it to int.Please help :(
public class Ch7LU3Ex1
{
public static void main(String[] args)
{
String[] str = new String []{"10.20","123456","12.invalid"};
int i,count=0;
try
{
for(i=0;i<3;i++)
{
int l = str[i].length();
for(int j=0;j<l;j++)
{
if(str[i].charAt(j)=='.')
{
count++;
}
else
{
continue;
}
}
if(count!=0)
{
double d = Double.parseDouble(str[i]);
System.out.println(d);
}
else
{
int e = Integer.parseInt(str[i]);
System.out.println(e);
}
}
}
catch(NumberFormatException e)
{
System.out.println("Invalid number");
}
}
}
if(str[i].indexOf('.') == -1) {
int e = Integer.parseInt(str[i]);
}
else {
double d = Double.parseDouble(str[i]);
}
This is much more elegant than all of your unneeded loops. Good luck!
To understand how this works, see the String API for indexOf().
As for the current way you are using, you need to reset the count to 0 in each iteration, else each of your values after first double value is found will be converted to double, since your count value is non-zero in every case.
So, in your first for loop, you need to reset the count at the start as follows: -
for(i=0;i<3;i++)
{
count = 0;
Now, you are really making your task complex. You don't need to use the count variable at all. Also, you don't need the nested loop there. You can do it simple one loop like this. Just don't work on individual characters on your own. Java library has methods which have already done it for you. Use them instead: -
for (String str: arr) {
if (str.contains(".")) {
double d = Double.parseDouble(str);
} else {
int i = Integer.parseInt(str);
}
}
The loop is used is called enhanced for-loop.
String#contains() method checks whether a string contains a certain character or not. Or, you can use String#indexOf() method to find the index of . in your string. And if it returns a positive value, then your string contains that character.
I wouldn't use a loop at all. I would assume you don't have random data and you know the type of each "column" should be.
String[] str = {"10.20", "123456", "12.invalid"};
double d = Double.parseDouble(str[0]);
int i = Integer.parseInt(str[1]);
String s = str[2];
If you don't know if a value should be a double or an int, you can always parse it as a double without loss of precision.
It seems you have to set count back to zero for each string and you are not doing it.
After one iteration set again count to zero count=0 , in your second iteration count is not zero hence again consider as a double value
You have to reset your count variable to 0 after every examined element. This way count is incremented since "10.20" includes a dot and is not reset for "123456".
Your code is a bit of a mess, but the point is that you don't reset your count for each member of the str.
So if you add a counter=0; in the loop that goes trough all the characters of one string, you'd probably get what you want?
some extra tips:
use readable variable names
indent your code
Related
Below is my code for the problem described on https://community.topcoder.com/stat?c=problem_statement&pm=14635. It keeps track of possible interleaves (as described in the problem description given) through a static variable countPossible.
public class InterleavingParentheses{
public static int countPossible = 0;
public static Set<String> dpyes = new HashSet<>(); //used for dp
public static Set<String> dpno = new HashSet<>(); //used for dp
public static void numInterleaves(char[] s1, char[] s2, int size1, int size2){
char[] result = new char[size1+size2];
numInterleavesHelper(result,s1,s2,size1,size2,0,0,0);
}
public static void numInterleavesHelper(char[] res, char[] s1, char[] s2, int size1, int size2, int pos, int start1, int start2){
if (pos == size1+size2){
if (dpyes.contains(new String(res))){
countPossible+=1;
}
else{
if(dpno.contains(new String(res))){
countPossible+=0;
}
else if (isValid(res)){
dpyes.add(new String(res));
countPossible+=1;
}
else{
dpno.add(new String(res));
}
}
}
if (start1 < size1){
res[pos] = s1[start1];
numInterleavesHelper(res,s1,s2,size1,size2,pos+1,start1+1,start2);
}
if (start2 < size2){
res[pos] = s2[start2];
numInterleavesHelper(res,s1,s2,size1,size2,pos+1,start1,start2+1);
}
}
private static boolean isValid(char[] string){
//basically checking to see if parens are balanced
LinkedList<Character> myStack = new LinkedList<>();
for (int i=0; i<string.length; i++){
if (string[i] == "(".charAt(0)){
myStack.push(string[i]);
}
else{
if (myStack.isEmpty()){
return false;
}
if (string[i] == ")".charAt(0)){
myStack.pop();
}
}
}
return myStack.isEmpty();
}
}
I use the scanner class to put in the input strings s1 = "()()()()()()()()()()()()()()()()()()()()" and s2 = "()()()()()()()()()()()()()()()()()" into this function and while the use of the HashSet greatly lowers the time because duplicate interleaves are accounted for, large input strings still take up a lot of time. The sizes of the input strings are supposed to be at most 2500 characters and my code is not working for strings that long. How can i modify this to make it better?
Your dp set is only used at the end, so at best you can save an O(n), but you've already done many O(n) operations to reach that point so the algorithm completexity is about the same. For dp to be effective, you need to be reducing O(2^n) operations to, say O(n^2).
As one of the testcases has an answer of 487,340,184, then for your program to produce this answer, it would need that number of calls to numInterleavesHelper because each call can only increment countPossible by 1. The question asking for the answer "modulo 10^9 + 7" as well indicates that there is a large number expected as an answer.
This rules out things like creating every possible resulting string, most string manipulation, and counting 1 string at a time. Even if you optimized it, then the number of iterations alone makes it unfeasible.
Instead, think of algorithms that have about 10,000,000 iterations. Each string has a length of 2500. These constraints were chosen on purpose so that 2500 * 2500 fits within this number of iterations, suggesting a 2D dp solution.
If you create an array:
int ways[2501][2501] = new int[2501][2501];
then you want the answer to be:
ways[2500][2500]
Here ways[x][y] is the number of ways of creating valid strings where x characters have been taken from the first string, and y characters have been taken from the second string. Each time you add a character, you have 2 choices, taking from the first string or taking from the second. The new number of ways is the sum of the previous ones, so:
ways[x][y] = ways[x-1][y] + ways[x][y-1]
You also need to check that each string is valid. They're valid if each time you add a character, the number of opening parens minus the number of closing parens is 0 or greater, and this number is 0 at the end. The number of parens of each type in every prefix of s1 and s2 can be precalculated to make this a constant-time check.
This question already has answers here:
Generating all permutations of a given string
(57 answers)
Closed 7 years ago.
I want to make a program that would un-jumble some words.
I need to try all possible combinations of the words that can be formed, and then check if it is contained in a String variable, named dict.
My code is:
public class UnJumble
{
public static void main(String args[])
{
String dict = "cat, rat, mat dog, let, den, pen, tag, art,";
String t = "tra";
int l = t.length();
for(int i=0; i<l; i++)
{
char a=t.charAt(i);
t = t.replaceFirst(a+"","");
l--;
for(int j=0; j<l; j++)
{
char b = t.charAt(j);
t = t.replaceFirst(b+"","");
l--;
for(int k=0; k<l; k++)
{
char c = t.charAt(k);
if(dict.contains(""+a+b+c+","))
{
System.out.println("\'"+a+b+c+"\' found.");
break;
}
}
l++;
t = new StringBuilder(t).insert(j,b+"").toString();
}
t = new StringBuilder(t).insert(i,a+"").toString();
l++;
}
}
}
The variable t contains the word to be un-jumbled.
With this code, the output is:
'rat' found.
'art' found.
I think that I would need as many for loops as there as characters in the String t.
But I want to make it able to un-jumble words of an unknown length. So how can I achieve this?
I have tried searching on the Internet, and on SO. I found some answers on SO that are written in other programming languages which I don't understand.
You should look for recursive methods.
For example, given a string str of n characters, you can write a function that basicaly do this :
List<String> compute(String str)
// TODO : Handle case where str has only 1 character
List<String> list = compute(str.substring(0,n-2))
// TODO : Compute all combinations of str[n-1] with list
return list;
I guess this can be improved a lot in some cases.
There is a tricky way to do this without a for loop for each letter in your variable t, but it's code-intensive.
You can set up a loop that counts in base n, where n is the length of t. Assume i is your counter: Each pass through that loop you use the individual digits in i as indices into t, then build a ' word' and test that word against your dictionary. You are using i two different ways: as a counter and as a set of digits that represent indices into your t.
For example, if your t has three letters then you want to count in base 3 like this: 012, 020, 021, 022, 100, 101, 110,111, and so forth. Now the logic needs to verify that your combination of digits is unique so you don't use a letter twice when you build a word.
It's a lot of work but the algorithm is correct. The benefit is that it works for strings of any length.
I know I will be voted down, but oh well.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
hello i worked on a recursive method to convert from int to string fully manual way, and i wanna know if that recursive method is efficient or not, and if you could help me to improve the code. Im new to algorithms so don't blame me if something looks like ugly... I've search on the internet but never looked for something like that :
public class IntToString {
public static String intToString(int number) {
return intToString(number, "", false);
}
private static String intToString(int number, String answer,
boolean isNegative) {
if (number < 0 && isNegative == false) {
isNegative = true;
number = -number;
}
if (number == 0)
if (isNegative)
return "-" + answer;
else
return answer;
System.out.println(number);
return intToString(number / 10, answer = number % 10 + answer,
isNegative);
}
// test
public static void main(String[] args) {
String ans = intToString(-324234);
System.out.println(ans);
}
}
No, it's not very efficient. Though it could be worse. At least it's still O(N) where N is the number of decimal digits in the given number.
invertInt is not really needed. You are using it because you are appending it to the answer that you pass down the the recursions, which will cause that number to be inverted. But there are at least two other ways to do it so that it won't be inverted.
If you note, there is only a very slight difference between the the way you handle negative numbers and positive numbers. Perhaps you can just run the same procedure for both of them, if you remember that processing a negative number is the same as processing its positive opposite, and tacking the - when you're done.
There is no reason for all the flags for negative and inversion. Both of them are only done at the top level. So you can do those things at the intToString(int number) function and not in your recursive function, and save yourself a lot of condition checking, and of course, the replaceAll() call.
There is no need to pass down the answer. You can base your return value on what the recursive call returned. Remember that for numbers like 1,2,3, you'll get the string '1','2','3'. So if you have 23, and you pass down 2, you can use the 2 you got to build your answer.
Your algorithm does not return the correct answer for 0. It's the correct answer when you think in recursive terms, but not when you call it with 0 from main. There are at least two ways to handle that.
And a bit of style advice:
Always indent your code properly.
You don't need to compare boolean values to true or false. If you have a boolean variable x, you can use if (x) or if (!x) rather than if (x==true) and if (x==false). Name your boolean variables in a way that will make this more intuitive, like isNegative or needsInversion. An if (isNegative) makes sense when you read it.
More detailed information in case you could not find the solution:
How do we avoid the inversion? There are two ways, basically. If you insist on passing down the answer, then instead of:
answer += num % 10;
Use:
answer = ( num % 10 ) + answer;
That is - append it to the left of the answer, not its right.
The approach I prefer is using the answer from the lower level. Suppose you have the number 123. So you pass down 12, and you get back the answer "12". Then you can use
return answer + ( num % 10 );
which will give you "123". This time, it's appended to the right.
Finally, here is the complete solution:
public static String intToString( int n ) {
if ( n == 0 ) {
return "0";
} else if ( n < 0 ) {
return "-" + positiveIntToString( -n );
} else {
return positiveIntToString(n);
}
}
private static String positiveIntToString( int n ) {
if ( n == 0 ) {
return "";
} else {
return positiveIntToString( n / 10 ) + ( n % 10 );
}
}
You have the public function that is what you expose to the world. The recursive function is private, and it is only called for positive numbers. If called with zero, it will return an empty string, which is good for the recursion, but not as a real solution.
So the public function first checks two possible issues. If the number is zero, it shouldn't be passed to the private function because it will not return the correct answer. Instead, just return the string "0", as it is the correct answer.
For a negative number, all we need to do is do the work for its counterpart, -n, which is positive and so will be acceptable to the private function. And then we add the "-" in front.
The recursive function for positive integers then becomes very simple: if it's zero, return empty string. For anything else, call itself with n/10, tack the n%10 to the right side of the result, and return that.
Here is also an alternative solution, without a private method:
public static String intToString( int n ) {
if ( n == 0 ) {
return "0";
} else if ( n < 0 ) {
return "-" + intToString( -n );
} else if ( n < 10 ) {
return "" + (n%10);
} else {
return intToString(n/10) + (n%10);
}
}
I actually consider this to be a slightly less efficient solution, because we do two more checks on each level. The check for negative will only be true once, at the top level. The check for zero will only be true if the function is called with zero in the first place. The check for single digit numbers is the current recursion end (because we can't stop the recursion at zero, otherwise we'll always get an extra "0" at the beginning).
Very new to Java: Trying to learn it.
I created an Array and would like to access individual components of the array.
The first issue I am having is how to I print the array as a batch or the whole array as indicated below? For example: on the last value MyValue4 I added a line break so that when the values are printed, the output will look like this: There has to be a better way to do this?
MyValue1
MyValue2
MyValue3
MyValue4
MyValue1
MyValue2
MyValue3
MyValue4
The next thing I need to do is, manipulate or replace a value with something else, example: MyValue with MyValx, when the repeat variable is at a certain number or value.
So when the repeat variable reaches 3 change my value to something else and then change back when it reaches 6.
I am familiar with the Replace method, I am just not sure how to put this all together.
I am having trouble with changing just parts of the array with the while and for loop in the mix.
My Code:
public static String[] MyArray() {
String MyValues[] = { "MyValue1", "MyValue2", "MyValue3", "MyValue4\n" };
return MyValues;
}
public static void main(String[] args) {
int repeat = 0;
while (repeat < 7) {
for (String lines : MyArray()) {
System.out.println(lines);
}
repeat = repeat + 1;
if (repeat == 7) {
break;
}
}
}
Maybe to use for cycle to be shorter:
for (int i = 0; i < 7; i++) {
for (String lines : MyArray()) {
// Changes depended by values.
if (i > 3) {
lines = MyValx;
}
System.out.println(lines); // to have `\n` effect
}
System.out.println();
}
And BTW variables will start in lower case and not end withenter (\n). So use:
String myValues[] = {"MyValue1", "MyValue2", "MyValue3", "MyValue4"};
instead of:
String MyValues[] = { "MyValue1", "MyValue2", "MyValue3", "MyValue4\n" };
and add System.out.println(); after eache inside cycle instead of this:
MyValues[n] = "value";
where n is the position in the array.
You may consider using System.out.println() without any argument for printing an empty line instead of inserting new-line characters in your data.
You already know the for-each loop, but consider a count-controlled loop, such as
for (int i = 0; i < lines.length; i++) {
...
}
There you can use i for accessing your array as well as for deciding for further actions.
Replacing array items based on a number in a string might be a bit trickier. A regular expression will definitely do the job, if you are familiar with that. If not, I can recommend learning this, because it will sure be useful in future situations.
A simpler approach might be using
int a = Integer.parseInt("123"); // returns 123 as integer
but that only works on strings, which contain pure numbers (positive and negative). It won't work with abc123. This will throw an exception.
These are some ideas, you might try out and experiment with. Also use the documentation excessively. ;-)
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
when given a input string i am suppose to break it up into two groups
char
int.
with these two groups i want to create a new alternating string.
for example
abc1234defgh567jk89
will transform into
a1b2c3d5e6f7j8k9
notice that the digit 4,g,h has been discarded.
i figured that a queue can be implemented in this case.
queue1> abc
queue2> 123
index 0 to 2 is a char
index three is a int, so for queue 2 we only take in 3 values.
my question is there a more efficient data structure to perform this operation?
and during implementation, how to i compare to see if a particular value is a int or a char?
please advise.
Treating the string as an array of char integers would make this easier to compare, as you can do a simple comparision on the entry. If array[x]>64 it is a character else it is a number. You can use two pointers to do the interleaving. One for character and the other for integer. Find a character and then advance the integer pointer until it finds a match, then advance them as long as they are both true, then fast forward both of them. For example:
char array[]=(char *)string;
int letter=array[0];
int number=array[0];
// Initialize
while(number >= 64)
number++;
while (letter<64)
letter++;
//Now that the pointers are initialized, interleave them.
while(letter>=64 && number<64)
{
output[i++]=letter;
output[i++]=number;
number++;
letter++;
}
// Now you need to advance to the next batch, so you need to see the comparison false and then true again.
....
You are right, a queue is a good data structure for this problem. If, however, you want fancier methods at hand, a Linked List would be another very similar alternative.
To check if a particular value is a letter or a number, you can use the Character class. For example,
String sample = "hello1";
Character.isLetter( sample.charAt(0) ); // returns true
Character.isLetter( sample.charAt(5) ); // returns false
how to i compare to see if a particular value is a int or a char?
You can do something like this:
String string = "abc1234defgh567jk89";
for(int i=0; i<string.length;i++){
int c = (int)string.charAt(i);
boolean isChar = 97<=c&&c<=122 || 65<=c&&c<=90;
boolean isNum = 48<=c&&c<=57;
if(!isChar && !isNum){
throw new IllegalArgumentException("I don't know what you are")
}
}
About the datastructutures, personally I will use two single linked list, one for chars and one for numbers and every character will be stored in a different node. Why?, well if you store the characters (in general, I mean chars and ints) in groups of threes later you will have to add more code to split those groups and put chars and ints together, putting them in a linked list makes sense because
you can put as much nodes as you want (or memory lets you but let's assume is infinite)
data will be stored in order (which looks like some kind of requirement you have in order to display the output, also this discards trees and stacks(FILO))
since you only need to go forward when generating the output a double linked list will be over engineering.
To generate the output:
Having two datastructures let's you add another check like:
if(listChars.size() != listNums.size()){
throw new IllegalArgumentException("Wrong input!!!")
}
Additionally,
Reviewing the list will take you O(n) time, memory used will be O(n), reviewing both list will take you O(n/m) where m is the size of the initial group of chars.
You can do that like this:
Iterator<Character> iterChar = listChar.iterator();
Iterator<Integer> iterNum = listChar.iterator();
String result = "";
while(iterChar.hasNext() && iterNum.hasNext() ){
result+=iterChar.next()+iterNum.next();
}
Finally, you can use queues or linked list here both give you the same in this scenario
To check if the next char is a letter or number you can use this:
public static boolean isNumber(char c) { return c >= '0' && c <= '9'; }
public static boolean isLetter(char c) { return c >= 'a' && c <= 'z'; }
These functions find the index of the next number or letter, starting at pos i:
public static int nextNumber(String s, int i) {
while(i < s.length() && !isNumber(s.charAt(i))) i++;
return i;
}
public static int nextLetter(String s, int i) {
while(i < s.length() && !isLetter(s.charAt(i))) i++;
return i;
}
You don't really need a data structure, all you need is 3 pointers:
public static String alternate(String s){
// pointers
int start = 0, mid = 0, end = 0;
StringBuilder sb = new StringBuilder(s.length());
while(end < s.length()){
// E.g. for 'abc1234' {start, mid, end} = {0, 3, 7}
start = Math.min(nextLetter(s, end), nextNumber(s, end));
mid = Math.max(nextLetter(s, end), nextNumber(s, end));
end = Math.max(nextLetter(s, mid), nextNumber(s, mid));
for(int i = 0; i < Math.min(mid - start, end - mid); i++)
sb.append(s.charAt(start + i)).append(s.charAt(mid + i));
}
return sb.toString();
}
Running the example below outputs the desired result: a1b2c3d5e6f7j8k9
public static void main(String... args){
System.out.println(alternate("abc1234defgh567jk89"));
}