I'm trying to write a program which accepts a word in lowercase, converts it into uppercase and changes the vowels in the word to the next alphabet. So far, I've done this:
import java.util.*;
class prg11
{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
System.out.println("Enter a word in lowercase.");
String word = sc.next();
word = word.toUpperCase();
int length = word.length();
char ch[] = new char[length+1];
for (int i = 0; i<=length; i++)
{
ch[i] = word.charAt(i);
if("aeiou".indexOf(ch[i]) == 0)
{
ch[i]+=1;
}
}
String str = new String(ch);
System.out.println(str);
}
}
The code compiles fine. But, when I run the program and enter a word, say 'hey', the word is printed in uppercase only. The vowels in it (in this case, 'e'), do not get changed to the next alphabet.
How do I resolve this? TIA.
Need to change three places, according to the code in the question.
word = word.toUpperCase();
int length = word.length();
// yours: char ch[] = new char[length + 1];
// resulting array needs to be as same length as the original word
// if not, there will be array index out of bound issues
char ch[] = new char[length];
// yours: for (int i = 0; i<=length; i++)
// need to go through valid indexes of the array - 0 to length-1
for (int i = 0; i < length; i++) {
ch[i] = word.charAt(i);
// yours: if ("aeiou".indexOf(ch[i]) == 0) {
// two problems when used like that
// 1. indexOf() methods are all case-sensitive
// since you've uppercased your word, need to use AEIOU
// 2. indexOf() returns the index of the given character
// which would be >= 0 when that character exist inside the string
// or -1 if it does not exist
// so need to see if the returned value represents any valid index, not just 0
if ("AEIOU".indexOf(ch[i]) >= 0) {
ch[i] += 1;
}
}
Here's a little concise version. Note the changes I've done.
String word = sc.next().toUpperCase();
char ch[] = word.toCharArray();
for (int i = 0; i < ch.length; i++) {
if ("AEIOU".indexOf(ch[i]) >= 0) {
ch[i] += 1;
}
}
Java doc of indexOf().
public int indexOf(int ch)
Returns the index within this string of the first occurrence of the specified character.
If a character with value ch occurs in the character sequence represented by this String object,
then the index (in Unicode code units) of the first such occurrence is returned.
For values of ch in the range from 0 to 0xFFFF (inclusive), this is the smallest value k such that:
this.charAt(k) == ch
is true. For other values of ch, it is the smallest value k such that:
this.codePointAt(k) == ch
is true. In either case, if no such character occurs in this string, then -1 is returned.
Parameters:
ch - a character (Unicode code point).
Returns:
the index of the first occurrence of the character in the character sequence represented by this object,
or -1 if the character does not occur.
I think this should do it, let me know if it doesn't
public class prg11 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a word.");
String word = sc.next();
sc.close();
word = word.toUpperCase();
int length = word.length();
char ch[] = new char[length+1];
for (int i = 0; i<length; i++) {
ch[i] = word.charAt(i);
if("AEIOU".indexOf(ch[i]) > -1) {
ch[i]+=1;
}
}
String str = new String(ch);
System.out.println(str);
}
}
Let me know if it works.
Happy coding ;) -Charlie
Use:
for (int i = 0; i<length; i++)
instead as the last index is length-1.
use for (int i = 0; i<=length-1; i++) instead of for (int i = 0; i<=length; i++) and if("AEIOU".indexOf(ch[i]) != -1) instead of if("aeiou".indexOf(ch[i]) == 0)
reason
1.array index starts from 0 that's why length-1
2. As you already made your string in upper case so check condition on "AEIOU"
3. every non-vowel character will return -1 so use if("AEIOU".indexOf(ch[i]) != -1)
"aeiou".indexOf(ch[i]) == 0 will only match 'a' characters (since that is the character at index 0). You should be looking for any index that is greater than -1. Additionally, since you've already converted the string to uppercase, you should be checking against "AEIOU" instead of "aeiou".
Related
I have reversed the string and have a for loop to iterate through the reversed string.
I am counting characters and I know I have a logic flaw, but I cannot pinpoint why I am having this issue.
The solution needs to return the length of the last word in the string.
My first thought was to iterate through the string backward (I don't know why I decided to create a new string, I should have just iterated through it by decrementing my for loop from the end of the string).
But the logic should be the same from that point for my second for loop.
My logic is basically to try to count characters that aren't whitespace in the last word, and then when the count variable has a value, as well as the next whitespace after the count has counted the characters of the last word.
class Solution {
public int lengthOfLastWord(String s) {
int count = 0;
int countWhite = 0;
char ch;
String reversed = "";
for(int i = 0; i < s.length(); i++) {
ch = s.charAt(i);
reversed += ch;
}
for(int i = 0; i < reversed.length(); i++) {
if(!Character.isWhitespace(reversed.charAt(i))) {
count++;
if(count > 1 && Character.isWhitespace(reversed.charAt(i)) == true) {
break;
}
}
}
return count;
}
}
Maybe try this,
public int lengthOfLastWord(String s) {
String [] arr = s.trim().split(" ");
return arr[arr.length-1].length();
}
Another option would be to use index of last space and calculate length from it:
public int lengthOfLastWord(String string) {
int whiteSpaceIndex = string.lastIndexOf(" ");
if (whiteSpaceIndex == -1) {
return string.length();
}
int lastIndex = string.length() - 1;
return lastIndex - whiteSpaceIndex;
}
String.lastIndexOf() finds the start index of the last occurence of the specified string. -1 means the string was not found, in which case we have a single word and length of the entire string is what we need. Otherwise means we have index of the last space and we can calculate last word length using lastIndexInWord - lastSpaceIndex.
There are lots of ways to achieve that. The most efficient approach is to determine the index of the last white space followed by a letter.
It could be done by iterating over indexes of the given string (reminder: String maintains an array of bytes internally) or simply by invoking method lastIndexOf().
Keeping in mind that the length of a string that could be encountered at runtime is limited to Integer.MAX_VALUE, it'll not be a performance-wise solution to allocate in memory an array, produced as a result of splitting of this lengthy string, when only the length of a single element is required.
The code below demonstrates how to address this problem with Stream IPA and a usual for loop.
The logic of the stream:
Create an IntStream that iterates over the indexes of the given string, starting from the last.
Discard all non-alphabetic symbols at the end of the string with dropWhile().
Then retain all letters until the first non-alphabetic symbol encountered by using takeWhile().
Get the count of element in the stream.
Stream-based solution:
public static int getLastWordLength(String source) {
return (int) IntStream.iterate(source.length() - 1, i -> i >= 0, i -> --i)
.map(source::charAt)
.dropWhile(ch -> !Character.isLetter(ch))
.takeWhile(Character::isLetter)
.count();
}
If your choice is a loop there's no need to reverse the string. You can start iteration from the last index, determine the values of the end and start and return the difference.
Just in case, if you need to reverse a string that is the most simple and efficient way:
new StringBuilder(source).reverse().toString();
Iterative solution:
public static int getLastWordLength(String source) {
int end = -1; // initialized with illegal index
int start = 0;
for (int i = source.length() - 1; i >= 0; i--) {
if (Character.isLetter(source.charAt(i)) && end == -1) {
end = i;
}
if (Character.isWhitespace(source.charAt(i)) && end != -1) {
start = i;
break;
}
}
return end == -1 ? 0 : end - start;
}
main()
public static void main(String[] args) {
System.out.println(getLastWord("Humpty Dumpty sat on a wall % _ (&)"));
}
output
4 - last word is "wall"
Firstly, as you have mentioned, your reverse string formed is just a copy of your original string. To rectify that,
for (int i = s.length() - 1; i >= 0; i--) {
ch = s.charAt(i);
reversed += ch;
}
Secondly, the second if condition is inside your first if condition. That is why, it will never break ( because you are first checking if character is whitespace, if it is, then you are not going inside the if statement, thus your second condition of your inner if loop will never be satisfied).
public class HW5 {
public static void main(String[] args) {
String s = "My name is Mathew";
int count = lengthOfLastWord(s);
System.out.println(count);
}
public static int lengthOfLastWord(String s) {
int count = 0;
int countWhite = 0;
char ch;
String reversed = "";
System.out.println("original string is----" + s);
for (int i = s.length() - 1; i >= 0; i--) {
ch = s.charAt(i);
reversed += ch;
}
System.out.println("reversed string is----" + reversed);
for (int i = 0; i < reversed.length(); i++) {
if (!Character.isWhitespace(reversed.charAt(i)))
count++;
if (count > 1 && Character.isWhitespace(reversed.charAt(i)) == true) {
break;
}
}
return count;
}
}
=
and the output is :
original string is----My name is Mathew
reversed string is----wehtaM si eman yM
6
Another way to go about is : you use the inbuilt function split which returns an array of string and then return the count of last string in the array.
I'm trying to make a code that deletes the repeated characters. For example - if we have a string "aabacdc", we want to make it as "abd". If the character exists twice in the string, then we delete both characters as we did in the above example. The 'a' occurs 3 times in our string, so we just deleted the 2 a and left 1 remaining.
What I'm trying to do in this code is use two nested for loops - first for loop to compare the first character with the other characters. If the character has a duplicate in the string, then just delete both the characters. How can I fix this code?
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str2 = input.nextLine();
StringBuilder str = new StringBuilder(str2);
for (int k = 0; k < str.length() - 1; k++) {
for (int i = 1; i < str.length() - 1; i++) {
if (str.charAt(k) == str.charAt(i)) {
str.deleteCharAt(k);
str.deleteCharAt(i);
}
}
}
System.out.println(str);
}
My interpretation of what you're trying to do based on your expected output is that you want to remove characters from the string 1 pair at a time. So if there is an odd number of a character in the string, 1 should remain, and if there's an even number 0 should remain.
Any time you're removing elements from a structure while you're iterating by index, you need to loop over the structure backwards, so that the index values don't shift as you delete elements. This means you should only delete elements which the outer loop is currently at, or has already seen (i.e. only delete elements at indexes >= i).
Scanner input = new Scanner(System.in);
String str = input.nextLine();
StringBuilder sb = new StringBuilder(str);
for (int i = sb.length() - 2; i >= 0; i--) {
for (int j = i + 1; j < sb.length(); j++) {
if (sb.charAt(i) == sb.charAt(j)) {
sb.deleteCharAt(j);
sb.deleteCharAt(i);
break;
}
}
}
System.out.println(sb);
Ideone Demo
I want get a String like this "SsjAasdLlswAasdMm"
and print a String like this "salam"
(print characters as String that are next to a Capital)
I wrote this :
import java.util.Scanner;
public class Temp {
public static void main(String[] args) {
char[] capitalalphabet = new char[]{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
Scanner input = new Scanner(System.in);
String s1 = input.next();
StringBuffer s2 = new StringBuffer();
for (int i=0 ; i < s1.length() ; i++) {
for (int j = 0; j < capitalalphabet.length; j++) {
if (s1.charAt(i) == capitalalphabet[j]){
int k = 0 ;
s2.setCharAt(k , s1.charAt(i+1));
k++;
}
}
}
System.out.println(s2);
}
}
and i got this error :
SAhfdsdEDsa
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.StringBuffer.setCharAt(StringBuffer.java:257)
at Temp.main(Temp.java:14)
It happens at this line:
s2.setCharAt(k, s1.charAt(i+1));
According to the documentation:
Throws:
StringIndexOutOfBoundsException - if start is less than zero, or greater than the length of this object.
Since your s2 string is empty (its length is 0), you're exceeding the bounds when you try to add to it.
Also, since your k variable is always initialized to zero right before the setChatAt method, and it's only defined inside the if-statement block, you'll always be setting at index 0, even if you could.
I'd suggest you just simply try to use StringBuilder instead, as well as discard the messy loop of captial letters - their ASCII code is sequential, you could simply ask if character is in range:
for (int i=0 ; i < s1.length()-1; i++) {
char c = s1.charAt(i);
if (c >= 'A' && c <= 'Z') {
s2.append(s1.charAt(i+1));
}
}
System.out.println(s2);
Note that the loop scans until the index before last, since it might access the next index (and since there's no need to check the last character - it cannot be followed by anything, capital or otherwise).
Note you could also replace the if condition with Character.isUpperCase(c) which is more readable and elegant.
Given a non-empty string str like "Code" print a string like "CCoCodCode". Where at each index in the string you have to reprint the string up to that index.
I know there is DEFINITELY something wrong with this code that I wrote because the answer should be CCoCodCode, but instead it's giving me the alphabet! I don't know how I should change it.
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String str = scan.next();
int x = str.length();
for(char i = str.charAt(0); i <= str.charAt(x-1); i++)
{
System.out.print(i);
}
}
The char datatype can be treated as a number; you can increment it and manipulate it as a number.
What you really want is successive substrings of str to be printed. Loop over an int that will represent the ending position of the substring to be printed.
for (int i = 0; i < str.length(); i++)
{
System.out.print(str.substring(0, i + 1));
}
The end index argument to substring is exclusive, which is why I added 1.
Let's say that str is "Code". We can perform some mental substitutions to see what happens to your loop.
str is "Code"
x is 4
str.charAt(0) is 'C'
str.charAt(x-1) is 'e'
Making these substitutions, your loop is:
for(char i = 'C'; i <= 'e'; i++)
{
System.out.print(i);
}
Does this help you see the problem? I would think you'd have a loop from 0 to 3, not from 'C' to 'e'...
Many ways to get it done, suppose we have the input from user stored in a string named "c"... then...
String c = "Code";
for (int i = 0; i < c.length(); i++) {
System.out.print(c.substring(0, i));
}
System.out.print(c);
And this will print the sequence you are looking for.
It is outputting the alphabet because you are printing the counter instead of the characters in the string!
As it is, the first iteration of the for loop will set i to the first character, print that, then the operation i++ will increment i by one. Wait, so if the first character is "C", so i = 'C', what is i++?
Well it turns out characters can be represented by numbers. For example, 'C' has a value of 67. So incrementing it makes it 68, which represents 'D'. So if you run the loop on "Code", it will increment your counter 4 times, giving "CDEF". If you run on "Codecodecode", that will make the loop run 12 times, giving "CDEFGHIJKLMN".
What you really want is to loop through the string by its index instead:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String str = scan.next();
int length = str.length();
for (int i = 0; i < length; i++) {
System.out.print(str.substring(0, i + 1));
}
}
Given two words, determine if the first word, or any anagram of it, appears in consecutive characters of the second word. For instance, tea appears as an anagram in the last three letters of slate, but let does not appear as an anagram in slate even though all the letters of let appear in slate.
Return the anagram of the first word that has appeared in the second word.
Sample Input 1
tea
slate
Sample Output1
ate
Sample Input 2
let
slate
Sample Output2
NONE
I tried below got struck
public static boolean testAnagram(String originalWord, String containedWord)
{
char [] first = originalWord.toCharArray();//Get the first word and store it into a character array.
char [] second = containedWord.toCharArray();//Get the second word and store it into a character array.
int [] index = new int[second.length];//An int array that stores the index of matching letters contained in the original array.
int counter = 0;//Keep count of the index storage position.
//Compare each character of both words.
for(int i = 0; i < second.length; i++)
{
for(int j = 0; j < first.length; j++)
{
if(second[i] == first[j])
{
index[counter] = j; //Store matching letters.
counter++; //Increment the index storage position.
break;//Break for loop.
}
}
}
if(counter < second.length)return false;//If not all letters were found.
//get the distance between the indices which should be no more than one
//less than the contained word length (to qualify as an anagram)
for(int i = 0; i < index.length; i++)
{
for(int j = 0; j = second.length)
{
//stuck here
return ;
}
}
//If all qualifications are met.
return ;
}
I suggest you do the following:
Iterate through each character in the second word (ex. slate)
When you find a character contained in the first word, get the substring that begins at this character with the length of the first word.
Check if this substring is an anagram of the first word.
String getSubAnagram (String s1, String s2){
for (int i = 0; i = s1.length(); i++) {
if(s1.indexOf(s2.charAt(i)) >-1){
if(isAnagram(s1, s2.substring(i, s1.length()+i)))
return s2.substring(i, s1.length()+i);
}
}
return null;
}
Use a forward-test for each next character in the shorter word, starting at each character in the longer word. To prevent double matches, erase the matching character in a copy of the longer word.
As soon as the next character in the longer word is not in the shorter word, you know there is no use in continuing.
The following is in ANSI C, so you need to adjust the string functions to Java equivalents. The compareForward function modifies the shorter word to prevent double matches -- it overwrites the original character with a space -- and so you need to make sure it runs on a copy of the input word. (I'm not sure if Java does so automatically.)
This needs sort of O(n*(m-n)) comparisons. (Note that the longer word only needs checking until a shorter word length remains; hence the strlen end condition in the for loop in my main.)
#include <stdio.h>
#include <string.h>
int compareForward (char *start, char *findThis)
{
char *copyOfFind, *comparePos, *ptr;
int loopCounter;
printf ("is '%c' in '%s' to begin with?\n", *start, findThis);
if (!strchr (findThis, *start))
{
printf ("first character not in shorter word, no use in continuing\n");
return 0;
}
printf (">\n");
/* C needs a copy because you'll modify the original word otherwise */
copyOfFind = strdup (findThis);
comparePos = start;
for (loopCounter=0; loopCounter < strlen(findThis); loopCounter++)
{
printf ("looking for '%c' in '%s'\n", *comparePos, copyOfFind);
ptr = strchr (copyOfFind, *comparePos);
if (!ptr)
{
printf ("not found, no use in continuing\n");
break;
}
*ptr = ' ';
comparePos++;
}
printf ("<\n");
free (copyOfFind);
/* Did we find all characters? */
return loopCounter == strlen(findThis);
}
int main (int argc, char **argv)
{
int loopy, match;
if (argc != 3)
{
printf ("invalid number of arguments\n");
return 0;
}
match = -1;
for (loopy=0; loopy < strlen(argv[2])-strlen(argv[1])+1; loopy++)
{
printf ("start at %s\n", argv[2]+loopy);
if (compareForward (argv[2]+loopy, argv[1]))
{
match = loopy;
break;
}
}
if (match >= 0)
{
printf ("match at pos %d: ", match);
for (loopy=0; loopy<strlen(argv[1]); loopy++)
printf ("%c", argv[2][match+loopy]);
printf ("\n");
} else
printf ("NONE\n");
return 0;
}
private static String isSubstringAnagram(String inp, String word) {
int inpLen = inp.length(), wordLen = word.length();
if (inpLen > wordLen) return "NONE";
Set<Character> hs = new HashSet<>();
for (char c : inp.toCharArray()) hs.add(c);
for (int i = 0; i < wordLen - inpLen + 1; i++) {
if (hs.contains(word.charAt(i))) {
boolean flag = isAnagram(inp, word, i, inpLen);
if (flag) return word.substring(i, i + inpLen);
}
}
return "NONE";
}
private static boolean isAnagram(String inp, String word, int idx, int len) {
int[] map = new int[26];
for (int i = 0; i < len; i++) {
map[inp.charAt(i) - 'a']++;
map[word.charAt(i + idx) - 'a']--;
}
for (int i = 0; i < 26; i++)
if (map[i] != 0)
return false;
return true;
}