why does this method take off the last letter in the string? - java

This is part of a java project, we have to take in a sentence that has multiple spaces between the world (a sentence like this) and convert it into a character array, then print out the sentence without all the extra spaces. It works, but it prints out the sentence missing the last letter.
Sentence Class:
public class sentences {
String sentence;
int length;
private char[] ch;
public sentences(String sentence, int length) {
this.sentence = sentence;
this.length = length;
char [] ch;
}
/**method that takes a string and turns it into an array then prints out the array
* makes an empty string and fills it with the char, takes out empty spaces
*
*/
public char[] makesentenceanarray(String sentence, int length) {
char[] ch = new char[sentence.length()];
//String noWhite = "";
StringBuilder s = new StringBuilder();
char prevchar = ' ';
for (int i = 0; i < sentence.length(); i++) {
ch[i] = sentence.charAt(i);
}
for(int j = 0; j < sentence.length(); j++) {
char currentchar = ch[j];
if( !(prevchar == ' ' && currentchar == prevchar)) {
s.append(prevchar);
}
prevchar = currentchar;
}
s.deleteCharAt(0);
System.out.println(ch);
System.out.print(s);
return ch;
}
}
Tester class:
import java.util.Scanner;
public class tester {
public static void main(String [] args) {
Scanner scan = new Scanner(System.in);
System.out.print("enter your sentence: ");
String a = scan.nextLine();
sentences s1 = new sentences(a, a.length());
s1.makesentenceanarray(a, a.length());
}
}
********************************************************************************
heres what I end up with:
enter your sentence: this is my sentence
this is my sentence
this is my sentenc
any help is appreciated thanks!

After the loop, append prevchar. Also, use StringBuilder.

You’re appending the previous character. Think instead about the circumstances under which you would append the current character. In you loop you will look at every current character, but for the very last character, the previous will be the second to last character and then the loop stops. Make sense?

sentence.length() starts counting at 1. (Yes I know it's inconsistent :D)Therefore you need to start counting at 1 and compare with <= at the first for loop.
public char[] makesentenceanarray(String sentence, int length) {
char[] ch = new char[sentence.length()];
//String noWhite = "";
StringBuilder s = new StringBuilder();
char prevchar = ' ';
for (int i = 1; i <= sentence.length(); i++) {
//you should do this now bc of the change of the for loop:
//ch[i - 1] = sentence.charAt(i - 1);
ch[i] = sentence.charAt(i);
}
for(int j = 0; j < sentence.length(); j++) {
char currentchar = ch[j];
if( !(prevchar == ' ' && currentchar == prevchar)) {
s.append(prevchar);
}
prevchar = currentchar;
}
//Now you should be able to delete this
//s.deleteCharAt(0);
System.out.println(ch);
System.out.print(s);
return ch;
}
}

Related

Java 'error: class expected' when usig array length method [duplicate]

This question already has an answer here:
What does "error: '.class' expected" mean and how do I fix it
(1 answer)
Closed 4 months ago.
I am doing an assignment for my Java class that requires me to write a program that displays the number of uppercase letters in a string. I am getting the error on my line 26 (for (int i = 0; i < ch[].length; i++){) any help would be appreciated.
import java.util.Scanner;
public class Uppercase{
public static void main(String[] args){
char[] newWord;
Scanner userWord = new Scanner(System.in);
System.out.println("Enter a word");
String word = userWord.nextLine();
System.out.println("There are " + newWord.numUppercase(word) + "uppercase letters");
}
public int numUppercase(String s){
char[] ch = new char[s.length()];
for (int i = 0; i < s.length(); i++){
ch[i] = s.charAt(i);
int uppercase = 0;
for (int i = 0; i < ch[].length; i++){
if(ch[i].valueOf() > 64 && ch[i].valueOf() < 91){
uppercase++;
}
}
return uppercase;
}
}
}
Your bug-fixed class:
public class Uppercase{
public static void main(String[] args){
Scanner userWord = new Scanner(System.in);
System.out.println("Enter a word");
String word = userWord.nextLine();
System.out.println("There are " + numUppercase(word) + "uppercase letters");
}
public static int numUppercase(String s){
char[] ch = new char[s.length()];
for (int i = 0; i < s.length(); i++){
ch[i] = s.charAt(i);
int uppercase = 0;
for (int j = 0; j < ch.length; j++){
if(ch[j] > 64 && ch[j] < 91){
uppercase++;
}
}
return uppercase;
}
return 0;
}}
Aside from the typo, the calculation of the uppercase letters is incorrect.
First, there's no need to create ch array, copy the characters from the input string, and then check the chars in ch array.
Second, an assumption that the uppercase letters reside in the range [65, 90] is applicable only to English letters. There are several Character::isUpperCase methods to check if a character or a Unicode codepoint is upper case. Character::isUpperCase(char c) has been existing for a while since Java 1.0.
So, that being said, an example counting uppercase letters could be as follows:
public static int numUpperCase(String s) {
int num = 0;
if (s != null) {
for (char c : s.toCharArray()) {
if (Character.isUpperCase(c)) num++;
}
}
return num;
}
A oneliner using Stream API:
static int numUpperCase(String str) {
return Optional.ofNullable(str)
.map(s -> (int) s.chars().filter(Character::isUpperCase).count())
.orElse(0); // if input string is null
}

How to replace odd/even chars in string with spaces in Java?

If given a string like "go to med!" how do I replace just the even characters for example? The problem is that while my code takes care of the first word, the space between the words counts as a character itself and messes up replacements in the second word with the first letter of the second word becoming classified as even.
Here is my attempt
public static void main(String[] args) {
String s = "go to med!";
String alphabetS = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder(s);
for(int i=0; i<s.length(); i++){
char currChar = s.charAt(i);
int idx = alphabetS.indexOf(currChar);
if (idx != -1)
if (i%2==1)
{
sb.setCharAt(i, '*');
}
}
System.out.println(sb);
}
This gives output "g+ +o m+d!"
(second letter being correctly replaced by + for being even, but the first letter of the second word should not be replaced as "first" is not "even".
How to make the index to ignore white spaces?
Preferably the answer should not contain arrays, only Char and String methods.
You could simply split the input on the space and process each work individually. You could then use a StringJoiner to piece together the result, for example...
String s = "go to med!!";
String alphabetS = "abcdefghijklmnopqrstuvwxyz";
String[] words = s.split(" ");
StringJoiner sj = new StringJoiner(" ");
for (String word : words) {
StringBuilder sb = new StringBuilder(word);
for (int i = 0; i < sb.length(); i++) {
char currChar = sb.charAt(i);
int idx = alphabetS.indexOf(currChar);
if (idx != -1) {
if (i % 2 == 1) {
sb.setCharAt(i, '*');
}
}
}
sj.add(sb.toString());
}
System.out.println(sj.toString());
which outputs
g* t* m*d!!
could this be done without using arrays - just with char and string methods?
Instead of relying on i, you need a separate counter, which tracks which point your up to and which can be used to ignore invalid characters, for example
String s = "go to med!!";
String alphabetS = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder(s);
int counter = 0;
for (int i = 0; i < sb.length(); i++) {
char currChar = sb.charAt(i);
int idx = alphabetS.indexOf(currChar);
if (idx != -1) {
if (counter % 2 == 1) {
System.out.println("!!");
sb.setCharAt(i, '*');
}
counter++;
}
}
System.out.println(sb.toString());
which still outputs
g* t* m*d!!
this gives: g* t* m*d*
public static void main(String[] args) {
String s = "go to med!";
int realindex=0;
StringBuilder sb = new StringBuilder();
for(int i=0; i<s.length(); i++){
char currChar = s.charAt(i);
if ((currChar != ' '))
{
if (realindex%2==1) {
currChar = '*';
}
realindex++;
}
sb.append(currChar);
}
System.out.println(sb.toString());
}
There are a thousand different ways to accomplish your goal, but assuming you want to keep using your solution, here is what you could do
public static void main(String[] args) {
String s = "go to med!! goodbye cruel world";
String alphabetS = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder(s);
for (int i = 0,relativePosition=0; i < s.length(); i++,relativePosition++) {
char currChar = s.charAt(i);
if(currChar == ' '){relativePosition=-1;continue;}
int idx = alphabetS.indexOf(currChar);
if (idx != -1)
if (relativePosition % 2 == 1)
sb.setCharAt(i, '*');
}
System.out.println(sb);
}
that prints
g* t* m*d!! g*o*b*e c*u*l w*r*d
What about introducing flag about even state of letter?
boolean isEven=false;
for(int i=0; i<s.length(); i++){
char currChar = s.charAt(i);
int idx = alphabetS.indexOf(currChar);
if (idx != -1)
if(isEven){
isEven=false;
sb.setCharAt(i, '*');
}else {
isEven = true;
}
}
}

Java words reverse

I am new to Java and I found a interesting problem which I wanted to solve. I am trying to code a program that reverses the position of each word of a string. For example, the input string = "HERE AM I", the output string will be "I AM HERE". I have got into it, but it's not working out for me. Could anyone kindly point out the error, and how to fix it, because I am really curious to know what's going wrong. Thanks!
import java.util.Scanner;
public class Count{
static Scanner sc = new Scanner(System.in);
static String in = ""; static String ar[];
void accept(){
System.out.println("Enter the string: ");
in = sc.nextLine();
}
void intArray(int words){
ar = new String[words];
}
static int Words(String in){
in = in.trim(); //Rm space
int wc = 1;
char c;
for (int i = 0; i<in.length()-1;i++){
if (in.charAt(i)==' '&&in.charAt(i+1)!=' ') wc++;
}
return wc;
}
void generate(){
char c; String w = ""; int n = 0;
for (int i = 0; i<in.length(); i++){
c = in.charAt(i);
if (c!=' '){
w += c;
}
else {
ar[n] = w; n++;
}
}
}
void printOut(){
String finale = "";
for (int i = ar.length-1; i>=0;i--){
finale = finale + (ar[i]);
}
System.out.println("Reversed words: " + finale);
}
public static void main(String[] args){
Count a = new Count();
a.accept();
int words = Words(in);
a.intArray(words);
a.generate();
a.printOut();
}
}
Got it. Here is my code that implements split and reverse from scratch.
The split function is implemented through iterating through the string, and keeping track of start and end indexes. Once one of the indexes in the string is equivalent to a " ", the program sets the end index to the element behind the space, and adds the previous substring to an ArrayList, then creating a new start index to begin with.
Reverse is very straightforward - you simply iterate from the end of the string to the first element of the string.
Example:
Input: df gf sd
Output: sd gf df
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
public class Count{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter string to reverse: ");
String unreversed = scan.nextLine();
System.out.println("Reversed String: " + reverse(unreversed));
}
public static String reverse(String unreversed)
{
ArrayList<String> parts = new ArrayList<String>();
String reversed = "";
int start = 0;
int end = 0;
for (int i = 0; i < unreversed.length(); i++)
{
if (unreversed.charAt(i) == ' ')
{
end = i;
parts.add(unreversed.substring(start, end));
start = i + 1;
}
}
parts.add(unreversed.substring(start, unreversed.length()));
for (int i = parts.size()-1; i >= 0; i--)
{
reversed += parts.get(i);
reversed += " ";
}
return reversed;
}
}
There is my suggestion :
String s = " HERE AM I ";
s = s.trim();
int j = s.length() - 1;
int index = 0;
StringBuilder builder = new StringBuilder();
for (int i = j; i >= 0; i--) {
Character c = s.charAt(i);
if (c.isWhitespace(c)) {
index = i;
String r = s.substring(index+1, j+1);
j = index - 1;
builder.append(r);
builder.append(" ");
}
}
String r=s.substring(0, index);
builder.append(r);
System.out.println(builder.toString());
From adding debug output between each method call it's easy to determine that you're successfully reading the input, counting the words, and initializing the array. That means that the problem is in generate().
Problem 1 in generate() (why "HERE" is duplicated in the output): after you add w to your array (when the word is complete) you don't reset w to "", meaning every word has the previous word(s) prepended to it. This is easily seen by adding debug output (or using a debugger) to print the state of ar and w each iteration of the loop.
Problem 2 in generate() (why "I" isn't in the output): there isn't a trailing space in the string, so the condition that adds a word to the array is never met for the last word before the loop terminates at the end of the string. The easy fix is to just add ar[n] = w; after the end of the loop to cover the last word.
I would use the split function and then print from the end of the list to the front.
String[] splitString = str.split(" ");
for(int i = splitString.length() - 1; i >= 0; i--){
System.out.print(splitString[i]);
if(i != 0) System.out.print(' ');
}
Oops read your comment. Disregard this if it is not what you want.
This has a function that does the same as split, but not the predefined split function
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the string : ");
String input = sc.nextLine();
// This splits the string into array of words separated with " "
String arr[] = myOwnSplit(input.trim(), ' '); // ["I", "AM", "HERE"]
// This ll contain the reverse string
String rev = "";
// Reading the array from the back
for(int i = (arr.length - 1) ; i >= 0 ; i --) {
// putting the words into the reverse string with a space to it's end
rev += (arr[i] + " ");
}
// Getting rid of the last extra space
rev.trim();
System.out.println("The reverse of the given string is : " + rev);
}
// The is my own version of the split function
public static String[] myOwnSplit(String str, char regex) {
char[] arr = str.toCharArray();
ArrayList<String> spltedArrayList = new ArrayList<String>();
String word = "";
// splitting the string based on the regex and bulding an arraylist
for(int i = 0 ; i < arr.length ; i ++) {
char c = arr[i];
if(c == regex) {
spltedArrayList.add(word);
word = "";
} else {
word += c;
}
if(i == (arr.length - 1)) {
spltedArrayList.add(word);
}
}
String[] splitedArray = new String[spltedArrayList.size()];
// Converting the arraylist to string array
for(int i = 0 ; i < spltedArrayList.size() ; i++) {
splitedArray[i] = spltedArrayList.get(i);
}
return splitedArray;
}

How to make alternate characters in a string to uppercase?

I wrote the following code but similar characters are always in the same case. What's wrong in this code and How can this problem be solved??
private void genBTActionPerformed(java.awt.event.ActionEvent evt) {
String str = new String(strTF.getText());
int n = str.length();
char ch;
int i;
for(i = 0; i < n; i++) {
if(i % 2 == 0) {
ch = Character.toLowerCase(str.charAt(i));
str = str.replace(str.charAt(i), ch);
} else {
ch = Character.toUpperCase(str.charAt(i));
str = str.replace(str.charAt(i), ch);
}
}
jumTF.setText(str);
}
Unlike what its name says, .replace() replaces characters/CharSequences in the whole input. The difference with .replaceAll() is that it takes literals as arguments and not regexes/regex replacements strings (and that it has an overload taking two chars as arguments). That is the second worst misnamed method of the String class after matches().
Moreover you create a new String on each character you replace, so you have n+1 strings for a n character long string. Do it like this instead:
final char[] chars = str.toCharArray();
final int len = chars.length;
char c;
for (int i = 0; i < len; i++) {
c = chars[i];
chars[i] = i % 2 == 0
? Character.toLowerCase(c)
: Character.toUpperCase(c);
}
jumTF.setText(new String(chars));
In your program you were using replace() which replaces characters/CharSequences in the whole input what you need to do is
Put the string into an array.
Iterate over said array.
convert that array back into string
private void genBTActionPerformed(java.awt.event.ActionEvent evt) {
String str = new String(strTF.getText());
char [] chr= str.toCharArray();
int n = chr.length;
char ch;
int i;
for(i = 0; i < n; i++) {
if(i % 2 == 0) {
ch = Character.toLowerCase(chr[i]);
chr[i]=ch;
} else {
ch = Character.toUpperCase(chr[i]);
chr[i]=ch;
}
}
jumTF.setText(new String(chr)); }
hope this will help you :)
Since String are immutable in java , you can use StringBuilder or StringBuffer to solve this problem
StringBuilder str=new StringBuilder(inputString);
You can use your own logic just with slight change instead of using
str = str.replace(str.charAt(i), ch);//since it replaces in whole string
Use
str.setCharAt(i,ch);
So your final Program looks like this :
for(i = 0; i < n; i++) {
if(i % 2 == 0) {
ch = Character.toLowerCase(str.charAt(i));
str.setCharAt(i,ch);
} else {
ch = Character.toUpperCase(str.charAt(i));
str.setCharAt(i,ch);
}
}
Suppose InputString is : stackoverflow
then output is : sTaCkOvErFlOw

how to convert Lower case letters to upper case letters & and upper case letters to lower case letters

Alternately display any text that is typed in the textbox
// in either Capital or lowercase depending on the original
// letter changed. For example: CoMpUtEr will convert to
// cOmPuTeR and vice versa.
Switch.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e )
String characters = (SecondTextField.getText()); //String to read the user input
int length = characters.length(); //change the string characters to length
for(int i = 0; i < length; i++) //to check the characters of string..
{
char character = characters.charAt(i);
if(Character.isUpperCase(character))
{
SecondTextField.setText("" + characters.toLowerCase());
}
else if(Character.isLowerCase(character))
{
SecondTextField.setText("" + characters.toUpperCase()); //problem is here, how can i track the character which i already change above, means lowerCase**
}
}}
});
setText is changing the text content to exactly what you give it, not appending it.
Convert the String from the field first, then apply it directly...
String value = "This Is A Test";
StringBuilder sb = new StringBuilder(value);
for (int index = 0; index < sb.length(); index++) {
char c = sb.charAt(index);
if (Character.isLowerCase(c)) {
sb.setCharAt(index, Character.toUpperCase(c));
} else {
sb.setCharAt(index, Character.toLowerCase(c));
}
}
SecondTextField.setText(sb.toString());
You don't have to track whether you've already changed the character from upper to lower. Your code is already doing that since it's basically:
1 for each character x:
2 if x is uppercase:
3 convert x to lowercase
4 else:
5 if x is lowercase:
6 convert x to uppercase.
The fact that you have that else in there (on line 4) means that a character that was initially uppercase will never be checked in the second if statement (on line 5).
Example, start with A. Because that's uppercase, it will be converted to lowercase on line
3 and then you'll go back up to line 1 for the next character.
If you start with z, the if on line 2 will send you directly to line 5 where it will be converted to uppercase. Anything that's neither upper nor lowercase will fail both if statements and therefore remain untouched.
You can use StringUtils.swapCase() from org.apache.commons
This is a better method :-
void main()throws IOException
{
System.out.println("Enter sentence");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
String sentence = "";
for(int i=0;i<str.length();i++)
{
if(Character.isUpperCase(str.charAt(i))==true)
{
char ch2= (char)(str.charAt(i)+32);
sentence = sentence + ch2;
}
else if(Character.isLowerCase(str.charAt(i))==true)
{
char ch2= (char)(str.charAt(i)-32);
sentence = sentence + ch2;
}
else
sentence= sentence + str.charAt(i);
}
System.out.println(sentence);
}
The problem is that you are trying to set the value of SecondTextField after checking every single character in the original string. You should do the conversion "on the side", one character at a time, and only then set the result into the SecondTextField.
As you go through the original string, start composing the output from an empty string. Keep appending the character in the opposite case until you run out of characters. Once the output is ready, set it into SecondTextField.
You can make an output a String, set it to an empty string "", and append characters to it as you go. This will work, but that is an inefficient approach. A better approach would be using a StringBuilder class, which lets you change the string without throwing away the whole thing.
String name = "Vikash";
String upperCase = name.toUpperCase();
String lowerCase = name.toLowerCase();
This is a better approach without using any String function.
public static String ReverseCases(String str) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char temp;
if (str.charAt(i) >= 'a' && str.charAt(i) <= 'z') {
temp = (char)(str.charAt(i) - 32);
}
else if (str.charAt(i) >= 'A' && str.charAt(i) <= 'Z'){
temp = (char)(str.charAt(i) + 32);
}
else {
temp = str.charAt(i);
}
sb.append(temp);
}
return sb.toString();
}
Here you are some other version:
public class Palindrom {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a word to check: ");
String checkWord = sc.nextLine();
System.out.println(isPalindrome(checkWord));
sc.close();
}
public static boolean isPalindrome(String str) {
StringBuilder secondSB = new StringBuilder();
StringBuilder sb = new StringBuilder();
sb.append(str);
for(int i = 0; i<sb.length();i++){
char c = sb.charAt(i);
if(Character.isUpperCase(c)){
sb.setCharAt(i, Character.toLowerCase(c));
}
}
secondSB.append(sb);
return sb.toString().equals(secondSB.reverse().toString());
}
}
StringBuilder b = new StringBuilder();
Scanner s = new Scanner(System.in);
String n = s.nextLine();
for(int i = 0; i < n.length(); i++) {
char c = n.charAt(i);
if(Character.isLowerCase(c) == true) {
b.append(String.valueOf(c).toUpperCase());
}
else {
b.append(String.valueOf(c).toLowerCase());
}
}
System.out.println(b);
Methods description:
*toLowerCase()* Returns a new string with all characters converted to lowercase.
*toUpperCase()* Returns a new string with all characters converted to uppercase.
For example:
"Welcome".toLowerCase() returns a new string, welcome
"Welcome".toUpperCase() returns a new string, WELCOME
If you look at characters a-z, you'll see that all of them have the 6th bit is set to 1. Where in A-Z 6th bit is not set.
A = 1000001 a = 1100001
B = 1000010 b = 1100010
C = 1000011 c = 1100011
D = 1000100 d = 1100100
...
Z = 1011010 z = 1111010
So all we need to do is to iterate through each character from a given string and then do XOR(^) with 32. In this way, the 6th bit can swap.
Look at the below code for simply changing the string case without using any if-else conditions.
public final class ChangeStringCase {
public static void main(String[] args) {
String str = "Hello World";
for (int i = 0; i < str.length(); i++) {
char ans = (char)(str.charAt(i) ^ 32);
System.out.print(ans); // Final Output: hELLO wORLD
}
}
}
Time Complexity: O(N) where N = Length of the string.
Space Complexity: O(1)
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String satr=scanner.nextLine();
String newString = "";
for (int i = 0; i < satr.length(); i++) {
if (Character.isUpperCase(satr.charAt(i))) {
newString+=Character.toLowerCase(satr.charAt(i));
}else newString += Character.toUpperCase(satr.charAt(i));
}
System.out.println(newString);
}
public class Toggle {
public static String toggle(String s) {
char[] ch = s.toCharArray();
for (int i = 0; i < s.length(); i++) {
char charat = ch[i];
if (Character.isUpperCase(charat)) {
charat = Character.toLowerCase(charat);
} else
charat = Character.toUpperCase(charat);
System.out.print(charat);
}
return s;
}
public static void main(String[] args) {
toggle("DivYa");
}
}
import java.util.Scanner;
class TestClass {
public static void main(String args[]) throws Exception {
Scanner s = new Scanner(System.in);
String str = s.nextLine();
char[] ch = str.toCharArray();
for (int i = 0; i < ch.length; i++) {
if (Character.isUpperCase(ch[i])) {
ch[i] = Character.toLowerCase(ch[i]);
} else {
ch[i] = Character.toUpperCase(ch[i]);
}
}
System.out.println(ch);
}
}
//This is to convert a letter from upper case to lower case
import java.util.Scanner;
public class ChangeCase {
public static void main(String[]args) {
String input;
Scanner sc= new Scanner(System.in);
System.out.println("Enter Letter from upper case");
input=sc.next();
String result;
result= input.toLowerCase();
System.out.println(result);
}
}
String str1,str2;
Scanner S=new Scanner(System.in);
str1=S.nextLine();
System.out.println(str1);
str2=S.nextLine();
str1=str1.concat(str2);
System.out.println(str1.toLowerCase());

Categories