Checking a string for a palindrome (java) (rookie status) [closed] - java

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.
I am trying to check to see if, entered a string, that the string is a palindrome
if it is display something positive
if not... something negative (invalid)
I am currently getting the answer invalid both times (no matter what is entered)
i'm not quite sure if there is a problem with the for loops or the boolean statement.
//ACTION FROM BUTTON PERFORMED HERE
private void ButtonActionPerformed(ActionEvent evt) {
//creating variables
String myString = textField1.getText();
int stringLength = myString.length();
char arrayOne[] = new char[stringLength];
char arrayTwo[] = new char[stringLength];
boolean palindrome = false;
//for loop to setup ARRAY ONE
for(int i = 0; i < stringLength-1; i++){
arrayOne[i] = myString.charAt(i);
}
//for loop to setup ARRAY TWO
for(int i = stringLength-1; stringLength-1 > i; i--){
arrayTwo[i] = myString.charAt(i);
}
//for loop checking if array indexes are equivalent in value (char)
for(int i = 0; i < stringLength-1; i++){
if(arrayOne[i] != arrayTwo[i]){
palindrome = false;
}
else{
palindrome = true;
}
}
//assigning text to the text boxes based on boolean palindrome
if(palindrome == true){
textField2.setText("Valid");
}
if(palindrome ==false){
textField2.setText("Invalid");
}
}
}
i think i commented it descently

Change
for(int i = stringLength-1; stringLength-1 > i; i--)
to
for(int i = 0; i < stringLength-1; i++)
and change
for(int i = stringLength-1; i-1 > 0; i--)
to
for(int i = stringLength-1; i-1 >= 0; i--)
EDIT:
That was a debugging fest!!
Here is a working code:
String myString = textField1.getText();
int stringLength = myString.length();
char arrayOne[] = new char[stringLength];
char arrayTwo[] = new char[stringLength];
boolean palindrome = true;
//for loop to setup ARRAY ONE
for(int i = 0; i <= stringLength-1; i++){
arrayOne[i] = myString.charAt(i);
}
//for loop to setup ARRAY TWO
for(int i = stringLength-1, pos = 0; i >= 0; i--, pos++){
arrayTwo[pos] = myString.charAt(i);
}
//for loop checking if array indexes are equivalent in value (char)
for(int i = 0; i <= stringLength-1; i++){
if(arrayOne[i] != arrayTwo[i]){
palindrome = false;
break;
}
}
//assigning text to the text boxes based on boolean palindrome
if(palindrome == true){
textField2.setText("Valid");
}
else{
textField2.setText("Invalid");
}

I agree with the other answers about your error, but I think a more concise solution would be
boolean isPalindrome(String myString) {
int n = myString.length;
for( int i = 0; i < n/2; i++ )
if (myString.charAt(i) != myString.charAt(n-i-1)) return false;
return true;
}
Your code would now be
private void ButtonActionPerformed(ActionEvent evt) {
String myString = textField1.getText();
textField2.setText( isPalindrome(myString) ? "Valid" : "Invalid" );
}

//for loop to setup ARRAY TWO
for(int i = stringLength-1; stringLength-1 > i; i--){
arrayTwo[i] = myString.charAt(i);
}
This falls over after the first iteration.
You need to change it to something like:
//for loop to setup ARRAY TWO
for(int i = stringLength-1; i > 0; i--){
arrayTwo[i] = myString.charAt(i);
}

This loop copies all characters except the last one which probably is not what you wanted:
//for loop to setup ARRAY ONE
for(int i = 0; i < stringLength-1; i++){
arrayOne[i] = myString.charAt(i);
}
It should probably be fixed like this:
//for loop to setup ARRAY ONE
for(int i = 0; i < stringLength; i++)
{
arrayOne [i] = myString.charAt (i);
}
Body of this loop:
//for loop to setup ARRAY TWO
for (int i = stringLength-1; stringLength-1 > i; i--)
{
arrayTwo [i] = myString.charAt (i);
}
is never executed, because initial value of i: stringLength - 1 does not satisfy loop condition: stringLength - 1 > i.
You should probably change it to be:
// For loop to setup ARRAY TWO
for (int i = 0; i < stringLength; i++)
{
arrayTwo [i] = myString.charAt (stringLength - i - 1);
}
Also, after this loop:
// for loop checking if array indexes are equivalent in value (char)
for (int i = 0; i < stringLength-1; i++)
{
if (arrayOne [i] != arrayTwo [i])
{
palindrome = false;
}
else
{
palindrome = true;
}
}
variable palindrome will contain result of last comparison only, so if all characters except the last ones were different but last characters were equal, palindrome will be true which is probably not what you wanted. Probably you should change the code like this:
palindrome = true;
for (int i = 0; i < stringLength; i++)
{
if (arrayOne [i] != arrayTwo [i])
{
palindrome = false;
}
}
Note that I also changed stringLength - 1 to stringLength, otherwise you were ignoring last characters.

The easiest way to test for a palindrome in java
String str = "Able was I ere I saw Elba"
boolean palindrome = str.equalsIgnoreCase(new StringBuilder(str).reverse().toString());
Yep, that's it.

public static void main(String[] args) {
String s = "akaq";
boolean b = false;
for (int i = 0, j = s.length() - 1; i < j; i++, j--) {
if (s.charAt(i) == s.charAt(j)) {
b = true;
continue;
} else {
b = false;
break;
}
}
if (b)
System.out.println("Palindrome");
else
System.out.println("Not Palindrome");
}
Try something like this instead of 2-3 for loops.

Change the first for loop from stringLength-1 to just stringLength because you are using < and not <=
Change the second for loop to
if(int i = stringLength-1; i>=0; i--)
Also, set palindrome to true by default and remove the
else{
palindrome = true;
}
part because now if the first and last characters of the loop are the same, but not the middle, it will return true.
EDIT: Also the third for loop should be stringLength and not stringLength-1 because you are using < and not <=

There's no need to copy everything into arrays. String is basically an array itself. You can access the individual characters with charAt().
Also there is no need to loop the entire length of the String since equality is associative.
So simply use :
public boolean isPalindrome(String s) {
for (int i = 0; i < s.length() / 2; i++) { // only until halfway
if (s.charAt(i) != s.charAt(s.length() - i - 1)) { // accessing characters of String directly
return false;
}
}
return true;
}
One last remark : if the String's length is odd, you don't need to check the middle chracter. So in the code above the diision by

Related

replacing all consecutive duplicates from the string with allowed no of occurrences [duplicate]

This question already has answers here:
How to replace multiple consecutive occurrences of a character with a maximum allowed number of occurences?
(2 answers)
Closed 3 years ago.
I need to write a method that takes a String as a parameter and returns a new String obtained by replacing every instance of repeated adjacent letters with a 'n' instances of that string.
For example, if "aaabcccd" as an input String and n =2, it returns "aabccd". I already tried the following code, but not getting expected output
String in = "aaadbbb";
char[] s = in.toCharArray();
int len = s.length;
int n = 2;
StringBuffer new_s = new StringBuffer("");
int count = 1;
char prev='\0';
for (int i = 0; i < len - 1; i++) {
if (s[i] == s[i + 1]) {
if(count <= n){
new_s.append(s[i]);
count++;
}else{
count=1;
}
} else {
new_s.append(s[i]);
}
}
System.out.println(new_s);
output-aaadb
expected-aadbb
Can be done with regexp magic using backreferences.
String in = "aaaaddbbbbc";
int n = 2;
String pattern = String.format("(([a-z])\\2{%d})\\2+", n - 1);
System.out.println(in.replaceAll(pattern, "$1"));
Outputs:
aaddbbc
Explanation:
The number inside {} is n-1.
([a-z]) is a capture group, matching any single lowercase letter from a to z. Since it's a second group of parentheses in the expression, it can be referenced as 2.
(([a-z])\\2{n}) means "match n+1 repetitions of same letter". It makes up a first capture group, and we'll use that as replacement
\\2+ matches all the extra repetitions of the same letter. They are discarded after replacement.
public static String test(String input, int repetitions) {
String flag = "";
String replacement = "";
String output = input;
ArrayList<Character> prevLetters = new ArrayList<Character>();
for(int x = 0; x < input.length(); x++) {
if(!prevLetters.contains(input.charAt(x))) {
for(int y = 0; y <= repetitions ; y++) {
flag += String.valueOf(input.charAt(x));
}
if(input.contains(flag)) {
replacement = flag.substring(0, flag.length()-1);
while(output.contains(flag)){
output = output.replace(flag, replacement);
}
}
flag = "";
prevLetters.add(input.charAt(x));
}
}
return output;
}
That is my solution, which follows a similar idea as yours. Rather than comparing each character value however, I thought it would be easier to simply check for a break in the rules (character appearing n+1 times in a row) and 'fix' it.
If you are interested in using your method, one potential issue that I noticed is that you aren't assigning count to 1 in your last else. You also won't have the chance to add the final character due to you only adding the character at index 'i' when the duration for the loop is len - 1.
To add one more alternative:
String in = "aaadbbbjjkllllllopp";
int n = 2;
StringBuilder sb = new StringBuilder();
char temp = in.charAt(0);
for(int i = 0; i < in.length()-1;){ // note that the incrementation of i is moved to the while loop
temp = in.charAt(i); // save current char in temp variable
int count = 0;
while (i < in.length() && in.charAt(i) == temp) { ///iterate as long as you find same chars or hit the end of the string
i++;
count++;
}
if (count > n){ // if and only if count is greater than max allowed set it to max allowed
count = n;
}
for(int j = 0; j < count; j++){ // append count chars
sb.append(temp);
}
}
System.out.println(sb.toString());
Look at this solution. You should take care of the last char in your input string, as you iterate only to the last but one.
private void replaceConsecutiveDuplicates() {
String input = "aaadbbb";
int n = 2;
StringBuffer sb = new StringBuffer();
int count = 1;
char current;
for( int i = 0; i < input.length(); ++i){
current = input.charAt(i);
if (i + 1 < input.length() && current == input.charAt(i + 1)) {
++count;
} else if (count > 1) {
for(int j = 0; j < n; ++j) {
sb.append(current);
}
count = 1;
}
else {
sb.append(current);
}
}
System.out.println(sb.toString());
}
I think you're on the right track. I'm not sure whether this is an assignment, so I don't want to just straight up give you an answer, but here are some hints that might help:
You're already iterating over the string. This is great! However, I think you want to compare the current character with the previous character, and not the next character.
You don't need to convert your input to a char array to iterate over it, just use charAt(idx)
You never seem to use prev, but I think you had the right idea in mind when you declared it!
Break your problem into two parts: When to update count and when to append a character. You can tackle both in your for loop, but instead of trying to do both things in the same if statements, break it up into multiple ifs.
The 3 things to do are:
Update Prev Value
Update Count
Update new String
Getting the right order for these and the exact implementation I'll leave to you (again, because I'm not sure if this is an assignment or not)
Update: Since others posted, here is my solution (with single for loop):
private String replaceConsecutiveDuplicates(String input, int n) {
if (input == null || input.length() < n) return input;
if (n == 0) return "";
StringBuffer sb = new StringBuffer();
int count = 1;
char prev = input.charAt(0);
sb.append(prev);
char current;
for( int i = 1; i < input.length(); i++) {
current = input.charAt(i);
if (prev == current) {
if (++count > n) continue;
} else {
count = 1;
}
prev = current;
sb.append(current);
}
return sb.toString();
}

Java program to print a character which is available only one time in the string [duplicate]

This question already has answers here:
Java: Print a unique character in a string
(20 answers)
Closed 4 years ago.
I am trying to print a character from a string which occurs only one time in the string. Here is the code I am using, but it is showing the answer always as H.
How can I fix this?
class StringRepeat {
static int i,j;
public static void main(String[] args) {
String s1 = "How are How";
outer:for(i=0;i<=s1.length(); i++)
{
inner:for(j=1;j<s1.length(); j++)
{
if (s1.charAt(i) != s1.charAt(j))
break outer;
}
}
System.out.println(s1.charAt(i));
}
}
Basically you can solve this in 2 ways - brute force (using arrays) and a bit more intelligently (using maps).
Brute force way
For every character in the input string check if it is the same as some other character:
public void uniqueCharsBruteForce(String input) {
for (int i = 0; i < input.length(); ++i) {
char candidate = input.charAt(i);
if (!contains(input, candidate, i)) {
System.out.println(candidate);
}
}
}
private boolean contains(String input, char candidate, int skipIndex) {
for (int i = 0; i < input.length(); ++i) {
if (i == skipIndex) {
continue;
}
if (candidate == input.charAt(i)) {
return true;
}
}
return false;
}
Code is simple but very slow, so use only for short strings. Time complexity is O(n^2).
Using maps
As you iterate through the input, count how many times each character appears. At the end, print only those who appear once only:
public void uniqueCharsBetter(String input) {
Map<Character, Integer> occurences = new HashMap<>();
for (int i = 0; i < input.length(); ++i) {
Character key = Character.valueOf(input.charAt(i));
occurences.put(key, occurences.getOrDefault(key, 0) + 1);
}
occurences.entrySet().forEach(entry -> {
if (entry.getValue().intValue() == 1) {
System.out.println(entry.getKey());
}
});
}
This can be optimized further but it's possible this is enough for your requirements. Time complexity is O(n).
This will give an StringIndexOutOfBoundsException if no unique
char is found:
outer:for(i=0;i<=s1.length(); i++)
replace it with
int i = 0;
outer: for(;i<s1.length(); i++)
There's no need for an inner label, and you need to start the search
from 0, not 1, so replace
inner:for(j=1;j<s1.length(); j++)
with
for(int j=0;j<s1.length(); j++)
You have your test inverted. If the characters at i and j are
the same, you need to continuue with the outer loop. Also, you need to
make sure you don't compare when i==j. So your test changes from:
if (s1.charAt(i) != s1.charAt(j))
break outer;
to
if (i!=j && s1.charAt(i) == s1.charAt(j))
continue outer;
If the inner for loop terminates, i.e. gets to the end of the
string, then the character at i is unique, so we need to break out
of the outer loop.
When you exit the outer loop you need to determine if you found a unique element, which will be the case if i < s1.length().
Putting this all together we get:
String s1= "How are How";
int i = 0;
outer: for(;i<s1.length(); i++)
{
for(int j=0;j<s1.length(); j++)
{
if (i!=j && s1.charAt(i) == s1.charAt(j))
continue outer;
}
break;
}
if(i<s1.length()) System.out.println(s1.charAt(i));
Here a link to the code (IDEOne).
This will print out every character that appears only once in the text.
final String s1 = "How are How";
outer:for(int i = 0; i < s1.length(); i++)
{
for(int j = 0; j < s1.length(); j++)
{
if(s1.charAt(i) == s1.charAt(j) && i != j)
{
continue outer;
}
}
System.out.println(s1.charAt(i);
}
Try this
String s = inputString.toLowerCase();
boolean[] characters = new boolean[26];
for(int i = 0; i < 26; i++)
characters[i] = true;
for(int i = 0; i < s.length(); i++)
{
if(characters[s.charAt(i) - 'a'])
{
System.out.println(s.charAt(i));
characters[s.charAt(i) - 'a'] = false;
}
}
Hope this helps. I have assumed that u treat lowercase and uppercase as same else u can modify accordingly

How to print the first recurring character in a string?

I got a school assignment that I have to create a program that prints the first recurring character in a given string.
For example, if the input is "helloo", then it should output as "l". I wrote the following code but it prints "l" and "o" both.
String text = "helloo";
int length = text.length();
for (int i = 0; i <= length - 1; i++) {
char curChar = text.charAt(i);
for (int j = i + 1; j <= length - 1; j++) {
if (curChar == text.charAt(j)) {
System.out.println(curChar);
break;
}
}
}
Can someone help me out with this? Thanks for any answers!
You're breaking just the inner loop but not the outer loop. You can use break with a label for the outer loop. For example:
String text = "helloo";
int length = text.length();
outerloop:
for (int i = 0; i <= length - 1; i++) {
char curChar = text.charAt(i);
for (int j = i + 1; j <= length - 1; j++) {
if (curChar == text.charAt(j)) {
System.out.println(curChar);
break outerloop;
}
}
}
Get more information here - How to break out of nested loops in Java?
Hope this helps, but you should try doing your school assignments yourself.
I realize that you are asking for a direct fix to your current approach. But for those who might read this question in the future, there is a very sleek approach here using regular expressions:
String text = "helloo";
String match = text.replaceAll("^.*?(.)\\1.*", "$1");
System.out.println(match);
l
Demo
The basic idea of the pattern ^.*?(.)\1 is to consume the least number of characters in the string until we hit a single character which is followed by that same character.
Here's another variant:
String text = "helloo";
ArrayList<String> a = new ArrayList<String>(Arrays.asList(text.split(Pattern.quote(""))));
for(int i = 0; i < a.size()-1;i++) {
if(a.get(i).compareTo(a.get(i+1)) == 0) {
System.out.println(a.get(i));
break;
}
class FirstRepeatingChar
{
public static void main(String args[])
{
String s="hello";
for(int i=0;i<s.length();i++)
{
for(int j=0;j<s.length();j++)
{
if(s.charAt(i)==s.charAt(j))
{
System.out.println(" the First non repeating character is " +s.charAt(i));
break;
}
}
}
}
}

How to see if two integers in an array are the same

Good day everyone.
I'm not quite sure on how to check for the same elements in an array example.
%java stuff 4 6 1 2 3 1
/* Now that there are two ones in the array it should pump out "Yes! The same!"*/
I do realize however that I can take the first value in the array and check that with a for loop and then so on and so forth.
I'm just not quite confident on the syntax yet.
So far I've tried putting up an if case for checking it put it doesn't work. Can anyone please be so kind and help me understand my project a little bit better?
P.s. I'm open towards all improvements of this question.
public class seeIT
{
public static void main (String[] args)
{
int N = args.length;
int [] a = new int[N];
boolean flag = false;
for ( int i = 0; i < N; i++)
{
a[i] = Integer.parseInt(args[0]);
}
for(int i = 0; i < N; i++)
for(int j = i +1; j < N; j++)
{ if(a[i] == a[j])
{ flag = true;
} else
{
System.out.print("correct, there are no numbers that are the same here");}
}
}
}
I created the boolean flag because, again, I realize that I need to check whether or not the statement is true or not.
Thank you all for kind answers and have a nice day.
Josef.
Add the elements to the set (HashSet), If the set.add returns false on the element, which means that element is repeated.
HashSet would be the class to use for this kind of problem, however it doesn't hurt to do it "manually" if you're learning. Here are some comments on your code:
a[i] = Integer.parseInt(args[0]);
I assume you meant
a[i] = Integer.parseInt(args[i]);
otherwise you would be putting args[0] at every position in a.
if(a[i] == a[j]) {
flag = true;
} else {
System.out.print("correct, there are no numbers that are the same here");
}
You are printing the result too soon - before you can know it. At this point you just know whether two particular elements are the same (and you correctly set the flag if they are), but you have to wait until the loops finish to know that there were no such elements in the whole array.
First of all, I would suggest using a HashSet since it would take care of all repetition checking for you. But since you are in a learning stage, I will rather stick with your approach here.
I suggest putting your array checking logic in a separate method that returns a boolean. This way, you can return true as soon as you find a repeated number (return immediately exits a method), thereby avoiding uselessly iterating over the rest of the array. This also makes your code reusable.
This gives the following code. I also did some reformatting to make the code more readable, and I corrected a typo that makes your code repeatedly add the first argument into the int array.
public class SeeIT {
public static void main(String[] args) {
int n = args.length;
int[] a = new int[n];
boolean flag = false;
for (int i = 0; i < n; i++) {
a[i] = Integer.parseInt(args[i]);
}
boolean repeats = hasRepetitions(a);
if (repeats) {
System.out.println("There is at least one repeated number.");
} else {
System.out.println("correct, there are no numbers that are the same here");
}
}
private static boolean hasRepetitions(int[] a) {
int n = a.length;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (a[i] == a[j]) {
return true;
}
}
}
return false;
}
}
I hope this will help...
Cheers,
Jeff
There are some flaws in your code:
This reads always the first element of the array: a[i] = Integer.parseInt(args[0]);, the boolean is never evaluated and the variable N is unnecessary (and in Java local variables should start with lower case).
I think, this is what you want:
int[] a = new int[args.length];
for (int i = 0; i < a.length; i++) {
a[i] = Integer.parseInt(args[i]);
}
for (int i = 0; i < a.length; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[i] == a[j]) {
System.out.print("same " + a[i]);
}
}
}
But a better way (as already mentioned) would be to use a HashSet. That way you do not even have to convert Strings to int. Just compare the values using equals() insted of ==. The code is even more simple:
public static void main(String[] args) {
java.util.Set<String> dbl = new java.util.HashSet<String>();
for (int i = 0; i < args.length; i++) {
for (int j = i + 1; j < args.length; j++) {
if (args[i].equals(args[j])) {
dbl.add(args[i]);
}
}
}
System.out.print("" + dbl.size() + " figure(s) appear more than once.");
java.util.Iterator<String> it = dbl.iterator();
while (it.hasNext()) {
System.out.print(" " + it.next());
}
}
public class SeeIT {
public static void main(String[] args) {
int [] a = new int[]{1,2,5,4,3,7,2};
boolean flag = false;
for(int i = 0; i< a.length; i++){
for(int j = 0; j< a.length; j++){
if(a[j] == a[i]){
if(j != i) {
flag = true;
}
}
}
}
if(flag == true){
System.out.println("Duplicates");
}else{
System.out.println("not duplicate");
}
}
}
}
This for-loop should do the trick. It's a double for-loop which iterates in the same array.

How to use System.in.read() in java?

I need to input and load some chars in a boolean 2-D array. If the char is X, mark the array element as true; else if the char is ., mark the array element as false.
Here is my design:
boolean[][] Array = new boolean[2][2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
if (System.in.read() == '.') {
Array[i][j] = false;
} else if (System.in.read() == 'X') {
Array[i][j] = true;
}
}
}
And, for example, if I type in .... or XXXX, it does not produce the correct result. Also for other input the result is not correct.
So how to deal with this?
You are reading a character a second time in the loop if the first character is not a '.'.
You should only read one character per loop. Save the character in a variable before your if statement, and then compare the variable to '.' and 'X' in turn.
You shouldn't call the read() function in each if statement. Call it one time and store it in a variable so you don't keep reading through the input. That could be one thing messing up your function. Another is how you are comparing chars with the == operator. Should use char.equals method for character comparison. Put a couple breakpoints in and see what values are being sent through to debug. Maybe try something like the following:
boolean[][] Array= new boolean[2][2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
Character input = (char)System.in.read();
if (input.equals('.')) {
Array[i][j] = false;
} else if (input.equals('X')) {
Array[i][j] = true;
}
}
}

Categories

Resources