I'm working on an assignment for my programming class but I've run into some difficulty and I'm not sure where else to look. Basically the question asks that we write a program that checks for palindromes.
The user enters text (No non-alphanumberic chars allowed.)
The String is pushed one character at a time into a stack
The characters are pulled one at a time out of the stack thus reversing the String
If the original is the same as the reverse, we have a palindrome
I'm having some trouble with my loops though and don't know where to go from here, does anyone have any advice or pointers? What am I doing wrong?
Here's what I have so far.
import java.util.Stack;
import java.util.regex.*;
import javax.swing.*;
public class Question1 {
static Stack PDrome = new Stack();
public static String Reverse (String input) {
String reverse;
if (input.length() <= 1) {
return input;
}
//pushing onto the stack
for (int i=0; i<input.length();i++) {
PDrome.push(input.charAt(i));
}
//popping from the stack into the string
for (int i=0; i<input.length(); i++) {
PDrome.pop()=reverse.charAt(i);
}
return reverse;
}
//Illegal char check method
public static boolean checker (String input) {
Pattern p = Pattern.compile("[^a-z0-9]", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(input);
boolean b = m.find();
if (b) {
System.out.println("There is a special character in your string");
System.exit(0);
}
return b;
}
//Main
public static void main (String [] args) {
//input
String input = JOptionPane.showInputDialog("Enter text to check if it's a palndrome");
//error case
if (input==null); {
System.out.println("Nothing Entered");
System.exit(0);
}
//checking for illegal chars
checker(input);
}
}
This part:
String reverse;
...
//popping from the stack into the string
for (int i=0; i<input.length(); i++)
{
PDrome.pop()=reverse.charAt(i);
}
should be like this:
String reverse = "";
...
//popping from the stack into the string
for (int i=0; i<input.length(); i++)
{
// appends the popped character to reverse
reverse += PDrome.pop();
}
note that when appending a large number of string, this isn't the best way to do it since Java's string is immutable and repeatedly appending a string would require creating a new string each time. This problem is small enough that it wouldn't really matter though, but when the problem gets large you'll want to use StringBuffer/StringBuilder.
PDrome.pop()=reverse.charAt(i); is wrong.
reverse is null -> NullPointerException
Are you assigning a value to a function? (pop())
You have to build reverse from pop'ping from the stack.
So you should start with an empty string: reverse = ""; and add the chars taken from the stack:
while (!PDrome.isEmpty())
reverse += PDrome.pop();
Naming detail
Please use non capital letters to start fields and method names:
"someIntegerVariable"
"methodForCalculation"
and only capital letters to start class and interface names:
Stack
ArrayList
MyClass
:)
(from the Java conventions)
What are you actually doing here?
PDrome.pop()=reverse.charAt(i);
You should have use PDrome.pop() to retrieve one char at a time and append it to reverse.
This is a much cleaner way to write it in my opinion. It is a recursive approach.
bool isPalindrome(String s)
{
if(s.length() <= 1)
return true;
return s[0] == s[s.length() - 1] && isPalindrome(s.substr(1, s.length() - 2);
}
It is MUCH shorter as you can see.
Related
My program has a String inputted Eg. hello i am john who are you oh so i see you are also john i am happy
my program then has a keyword inputted Eg. i (the program doesn't like capitals or punctuation yet)
then it reads the initial String and finds all the times it mentions the keyword + the word after the keyword, Eg. i am, i see, i am.
with this is finds the most common occurrence and outputs that second word as the new keyword and repeats. this will produce
i am john/happy (when it comes to an equal occurrence of a second word it stops (it is meant to))
What i want to know is how i find the word after the keyword.
package main;
import java.util.Scanner;
public class DeepWriterMain {
public static void main(String[] args) {
String next;
Scanner scanner = new Scanner(System.in);
System.out.println("text:");
String input = scanner.nextLine();
System.out.println("starting word:");
String start = scanner.nextLine();
input.toLowerCase();
start.toLowerCase();
if (input.contains(start)) {
System.out.println("Loading... (this is where i find the most used word after the 'start' variable)");
next = input.substring(5, 8);
System.out.println(next);
}else {
System.out.println("System has run into a problem");
}
}
}
If you use split to split all your words into an array, you can iterate through the array looking for the keyword, and if it is not the last in the array, you can print the next word
String arr [] = line.split(" ");
for (int i = 0; i < arr.length -1; i++) {
if (arr[i].equalsIgnoreCase(keyword)) {
sop(arr[i] + " " arr[i + 1]);
}
if it is not the last in the array, iterate only to length - 1
The String class includes a method called public int indexOf(String str). You could use this as follows:
int nIndex = input.indexOf(start) + start.length()
You then only need to check if nIndex == -1 in the case that start is not in the input string. Otherwise, it gets you the position of the first character of the word that follows. Using the same indexOf method to find the next space provides the end index.
This would allow you to avoid a linear search through the input, although the indexOf method probably does one anyway.
i've been looking at every post with the word palindrome, but i haven't come across any with the same sort of issue i'm having...
my goal is to identify palindromes using three stacks - when "madam" is inputted, the output should be "madam is a palindrome" and when "orange" is inputted, the output should be "orange is not a palindrome". i am only able to get the "...is a palindrome" output, no matter what
i'm trying to follow the following algorithm:
push every character into original stack and temporary stack
pop every character off temporary stack and push character into new stack (reverse the order)
compare original stack to reversed stack
the thought process behind this is that every time one of the characters in the original stack don't match the reversed stack, the variable mismatches is incremented and if there is more than zero mismatches, the word entered is a palindrome
here is the code:
import java.util.Scanner;
import java.util.Stack;
public class Palindrome {
public static boolean is_palindrome(String input) {
Stack<Character> original = new Stack<Character>();
Stack<Character> reversedStack = new Stack<Character>();
Stack<Character> tempStack = new Stack<Character>();
Character letter; //one character from the input string
int mismatches = 0; //number of spots that mismatched
int index; //index for the input string
for(index = 0; index < input.length(); index++) {
letter = input.charAt(index);
if(Character.isLetter(letter)) {
original.push(letter);
tempStack.push(letter);
}
reversedStack.push(tempStack.pop());
}
while(!original.isEmpty()) {
if(!original.pop().equals(reversedStack.pop())) { mismatches++; }
}
return (mismatches == 0);
}
//main() method, used for testing program
#SuppressWarnings("resource")
public static void main(String[] args) {
Scanner input = new Scanner(System.in); //user input
String word; //one input line
do {
System.out.print("Enter a word: ");
word = input.nextLine();
if(is_palindrome(word)) { System.out.println(word + " is a palindrome."); }
else { System.out.println(word + " is not a palindrome."); }
break;
} while(word.length() != 0);
}
}
any hints as to why this is only printing "...is a palindrome"?
Let's assume that the input is all letters. Then, your initial for loop will:
Push the letter onto original.
Push the letter onto tempStack.
Pop tempStack, and push that onto reversedStack.
In other words, that's just a silly way to do:
Push the letter onto original
Push the letter onto reversedStack
tempStack remains empty.
Clearly not what you want. You need a new, separate while loop for the 'pop tempStack and push into reversedStack' feature.
NB: As a sidenote, this is a crazy complicated algorithm to do the job, but presumably the assignment is to learn about stacks, and to do so by doing a Rube Goldberg machine job. Just in case that wasn't the point, this can be done near trivially by simply looping once, from 0 to half the input length, and comparing the char at index i with the char at index len - i. The entire methods can fit in 4 lines and takes zero objects to get the job done.
You do not need three stacks. It can be solved using a single stack.
Push each character to a Stack.
Compare the popped characters with the characters of the string from the beginning. Return false as soon as a mismatch is found; otherwise, return true if all characters match.
Demo:
import java.util.Stack;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(isPallindrome("madam"));
System.out.println(isPallindrome("orange"));
}
static boolean isPallindrome(String s) {
Stack<Character> stack = new Stack<>();
char[] arr = s.toCharArray();
for (char c : arr) {
stack.push(c);
}
for (char c : arr) {
if (c != stack.pop()) {
return false;
}
}
return true;
}
}
Output:
true
false
However, if you are free to use any other way to solve it, given below is a simpler way:
public class Main {
public static void main(String[] args) {
// Test
System.out.println(isPallindrome("madam"));
System.out.println(isPallindrome("orange"));
}
static boolean isPallindrome(String str) {
return new StringBuilder(str).reverse().toString().equals(str);
}
}
Output:
true
false
This is extremely complicated approach! You can decide whether a word is palindrome in just one for loop (and you have to go through just half the word) - compare chars at index i and index length - i, go through Math.floor(wordLength / 2) chars and if you have one mismatch, it's not palindrome - break loop and print fail...
So I have been doing competitive programming using java, my code is ACCEPTED in codeforces. But I still think this code doesn't look so good, cause it needs 2 "for loops" to identify the duplication. if it is only one "for loops", it still has duplication in the strings.
This is the problem: https://codeforces.com/problemset/problem/236/A.
So basically, the code will try to find the distinct characters in the strings, then if the length of the string is odd, it will print "IGNORE HIM", else "CHAT WITH HER!".
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String a;
int counter=0;
Scanner sc= new Scanner(System.in);
a=sc.next();
StringBuilder b= new StringBuilder(a);
int count = 0;
for(int i=0;i<b.length();i++)
{
for(int j=i+1;j<b.length();j++) {
if(b.charAt(i)==b.charAt(j)) {
b=b.deleteCharAt(j);
}
}
}
for(int i=0;i<b.length();i++)
{
for(int j=i+1;j<b.length();j++) {
if(b.charAt(i)==b.charAt(j)) {
b=b.deleteCharAt(j);
}
}
}
counter=b.length();
if(counter%2==0)
{
System.out.println("CHAT WITH HER!");
}
else
{
System.out.println("IGNORE HIM!");
}
}
}
You can replace most of this code by this one line:
int count = a.chars().distinct().count();
This transforms you string input into a stream of characters, gets the distinct values and returns the count.
Using streams is a good option. If you want to go plain old route, then you can use a hashset. Basically if character is in hashset, then move to next char, else add to hashset and increase counter by 1.
Building upon and completing #Guillaume's answer
String a = "xiaodao";
String out = a.chars().distinct().count() % 2 == 0 ? "CHAT WITH HER!" : "IGNORE HIM!";
System.out.println(out);
I would use a Hashset because it will contain a distinct set of all characters you add. You can just go through the list once and use size() to get the unique character count.
...
Set<Character> characters = new HashSet<>()
for(int i=0;i<b.length();i++)
{
characters.add(b.charAt(i));
}
if(characters.size()%2==0) {
...
I am trying to take a user inputted string and move the first letters before the first vowel to the end of the string. I'm stuck here, and just need a suggestion.
This is in java by the way
Find the index at which the first vowel is (suppose x), then use substring..
String modified = mystring.substring(x, mystring.length()) + mystring.substring(0, x);
Read the api for what substring actually does.
Okay. Here's the main method of the program that does what you need.
public static void main(String args[]){
String s;
int i=0;
//presume s gets user's input here
for(i=0;i<s.length();i++){
char c=s.charAt(i);
if(c=='a'||c=='A'||c=='e' || ...)
break;
}
if(i!=(s.length()-1)){
for(int j=i;j<s.length();j++)
System.out.print(s.charAt(j));
//displays from first vowel to end of string
}
else{
System.out.println("String ain't got any vowels.");
}
}
I want to write a program that decrypts an input string. It selects 0,2,4,6,8 etc. characters from each section of text input and displays it in reverse in the decryption output.
Input: bxoqb swi eymrawn yim
Output: my name is bob
Keep in mind that the program ignores the space symbol, and repeats the loop at the beginning of each word!
I couldn't find anything on the net that isn't based on a more complicated encryption/decryption systems. I'm starting with the simple stuff, first.
edit: Yes, my question is how do I learn how to do this? Or if someone could teach me a technique to decode strings like this?
pseudo code:
Split your string based of space and store it in list.
iterate your list, get each string(bxoqb) and now extract characters(bob) as you want and save it
Iterate same list in reverse order.
Hope it helps you to start.
The following code is the most straightforward way...
//code starts
public static void main(String[] args) {
String str = "bxoqb swi eymrawn yim";
String ans = decryption(str);
System.out.println(ans);
}
public static String decryption(String str) {
String ans = "";
String[] words = str.split(" ");
for (String s : words) {
for (int i = 0; i < s.length(); i += 2) {
ans = s.charAt(i) + ans;
}
ans = " " + ans;
}
return ans.trim();
}
//code ends
Hope it helps.