I'm trying to figure out how to use a loop to append the delimiter ":" before the String s is found to contain a letter A-F.
If I have s = "10584f" then I would want the output to be "10584:f"
How should I go about doing this?
This is a simple solution that checks if it contains letters between a to f and put `:' accordingly.
public static void main(String[] args) {
String s = "10584f";
String newString = "";
for(int i=0;i<s.length();i++) {
if((int)s.charAt(i)>= (int)'a' && (int)s.charAt(i)<= (int)'f') {
newString = newString + ":" + s.charAt(i);
}else {
newString = newString + s.charAt(i);
}
}
System.out.println(newString);
}
You need to check for the ASCII code of each character and append the delimiter before it on this condition:
public class Main {
public static void main(String[] args) {
String s = "10584f";
System.out.println(appendDelimiter(s));
}
private static String appendDelimiter(String s) {
StringBuilder sb = new StringBuilder();
for(char c : s.toCharArray()) {
int charCode = (int) c;
if((charCode >= 65 && charCode <= 70) || (charCode >= 97 && charCode <= 102))
sb.append(":");
sb.append(c);
}
return sb.toString();
}
}
Output:
10584:f
If your target string consists of digits followed by a single letter from A-F or a-f, a simple solution can be: replacement of the regex-match, (\\d+)([A-Fa-f]). This regex means group(1) consisting of digits and group(2) consisting of a letter from A-F or a-f. The regex can be replaced with $1:$2 where $1 and $2 specify group(1) and group(2) respectively.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// Test strings
String[] arr = { "10584f", "12345A", "13456b", "23456F" };
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i].replaceAll("(\\d+)([A-Fa-f])", "$1:$2");
}
// After replacement
System.out.println(Arrays.toString(arr));
}
}
Output:
[10584:f, 12345:A, 13456:b, 23456:F]
However, if the string can have multiple letters followed by digits and you want each letter to be prepended with a :, you can iterate the string starting from the index, 1 until the last character of the string and if you come across a letter, prepend it with a : as done in the function, withColonBeforeLetters given below:
Demo:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// Test strings
String[] arr = { "10584f", "12345A", "13456b", "23456F", "1abc", "123aBc" };
for (int i = 0; i < arr.length; i++) {
arr[i] = withColonBeforeLetters(arr[i]);
}
// After replacement
System.out.println(Arrays.toString(arr));
}
static String withColonBeforeLetters(String s) {
StringBuilder sb = new StringBuilder();
// Put the first letter into sb
sb.append(s.charAt(0));
for (int i = 1; i < s.length(); i++) {
char ch = s.charAt(i);
if ((ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) {
sb.append(':').append(ch);
} else {
sb.append(ch);
}
}
return sb.toString();
}
}
Output:
[10584:f, 12345:A, 13456:b, 23456:F, 1:a:b:c, 123:a:B:c]
Related
Im a beginner java programmer and I am stuck on a little problem with my university coursework.
Basically I have a string that I want to iterate through and replace all instances of the letter 'a' or 'e' with the letter 'z'. For example, if the original string was "hello alan", the final string should be "hzllo zlzn".
We need to do this using a character array which holds the characters 'a' and 'e' to test against the string.
I've included my code below, we need to use the charAt() method also.
public static void main(String[] args) {
String a = ("what's the craic?");
char letters[] = new char[]{'a', 't'};
System.out.println("Before:" + a);
System.out.println("After: " + removeCharacters(a, letters));
}
public static String removeCharacters(String sentence, char[] letters) {
for (int i = 0; i < sentence.length(); i++) {
for (int j = 0; j < letters.length; j++) {
if (sentence.charAt(i) == letters[j]) {
sentence = sentence.replace(sentence.charAt(i), 'z');
} else {
sentence = "No changes nessesary";
}
}
}
return sentence;
}
Please help me with this problem. Im not sure where I am going wrong! Thanks.
if You are allowed to use replaceAll as well
"hello alan".replaceAll( "[ae]", "z" ); // hzllo zlzn
In difference to replace uses replaceAll a Pattern internally, which is compiled from the first argument [ae] to find the part to substitute with the second argument z. This solution is elegantly short, but slow, because the Pattern has to be compiled each time replaceAll is called.
otherwise use a StringBuilder
char[] letters = new char[] { 'a', 'e' };
StringBuilder buf = new StringBuilder( "hello alan" );
IntStream.range( 0, buf.length() ).forEach( i -> {
for( char c : letters )
if( buf.charAt( i ) == c )
buf.replace( i, i + 1, "z" );
} );
String s = buf.toString(); // hzllo zlzn
In difference to a String the contents of a StringBuilder is mutual (means you can change it). So it only has to be created once and all substitutions can be made in place.
Try this:
public static void main(String[] args) {
String a = "hello alan";
System.out.println("Before:" + a);
System.out.println("After: " + removeCharacters(a));
}
public static String removeCharacters(String sentence) {
if (!sentence.contains("a|e"))
return "No changes necessary";
return sentence.replaceAll("a|e", "z");
}
output 1:
Before:hello alan
After: hzllo zlzn
output 2:
Before:hi world
After: No changes necessary
Since you're forced to use charAt(...), one way would be like this:
public static String removeCharacters(String sentence, char[] letters) {
String output = "";
boolean wasChanged = false;
for (int i = 0; i < sentence.length(); i++) {
char ch = sentence.charAt(i);
for (int j = 0; j < letters.length; j++)
if (ch == letters[j]) {
ch = 'z';
wasChanged = true;
break;
}
output += ch;
}
if (wasChanged)
return output;
else
return "No changes necessary";
}
Since String::replace(char oldChar, char newChar) returns a new string resulting from replacing all occurrences of oldChar in this string with newChar, you do not need nested loops to do it. An efficient way of doing it can be as follows:
public static String removeCharacters(String sentence, char[] letters) {
String copy = sentence;
for (char letter : letters) {
sentence = sentence.replace(letter, 'z');
}
if (sentence.equals(copy)) {
sentence = "No changes nessesary";
}
return sentence;
}
Demo:
public class Main {
public static void main(String[] args) {
// Test
System.out.println(removeCharacters("hello stackoverflow", new char[] { 'a', 'e' }));
System.out.println(removeCharacters("world", new char[] { 'a', 'e' }));
}
public static String removeCharacters(String sentence, char[] letters) {
String copy = sentence;
for (char letter : letters) {
sentence = sentence.replace(letter, 'z');
}
if (sentence.equals(copy)) {
sentence = "No changes nessesary";
}
return sentence;
}
}
Output:
hzllo stzckovzrflow
No changes nessesary
How to get upper case instead of lower case in a string without method toUppercase, but the other symbols should not change in the string
package com.telukhin.hw6;
public class Task1 {
public static void main(String[] args) {
} private static String lowerCase(String s) {
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if(ch >= 'a' && ch < 'z') {
ch = ch - '32';
}
}
}
}
You can do it as follows:
public class Task1 {
public static void main(String[] args) {
System.out.println(lowerCase("HELLO"));
}
private static String lowerCase(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch >= 65 && ch <= 90)
sb.append((char)(ch+32));
else
sb.append((char)ch);
}
return sb.toString();
}
}
Output:
hello
Please check https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html for reference.
UPDATE: Adding a method to convert a String to upper case as well
public class Task1 {
public static void main(String[] args) {
System.out.println(lowerCase("HELLO"));
System.out.println(upperCase("hello"));
}
private static String lowerCase(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch >= 65 && ch <= 90) //ASCII value of 'A'is 65 and that of 'Z' is 90
sb.append((char)(ch+32));
else
sb.append((char)ch);
}
return sb.toString();
}
private static String upperCase(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch >= 97 && ch <= 122) //ASCII value of 'a'is 97 and that of 'z' is 122
sb.append((char)(ch-32));
else
sb.append((char)ch);
}
return sb.toString();
}
}
Output:
hello
HELLO
ASCII value of lowercase char a to z ranges from 97 to 122
ASCII value of uppercase char A to Z ranges from 65 to 92
For conversion we are adding 32 from the ASCII value of input char.
Add this in your if statement:
ch = ch + 32;
Assuming this isn't homework, which the limit of not using toUppercase sort of implies, you could do this:
public class Main
{
public static void main(String[] argv)
{
final String upper = toUpperCase("HELLO1234#world.CoM");
System.out.println(upper);
}
private static String toUpperCase(final String s)
{
final StringBuilder builder = new StringBuilder();
for(final char c : s.toCharArray())
{
final char upper = Character.toUpperCase(c);
builder.append(upper);
}
return builder.toString();
}
}
This will handle non-ascii characters. Alternatively, you can still use the 65 and 90 bit in place of Character.toUpperCase
One more example. This converts the string to an array of characters for working with, and then creates a new string with the result. It seems more convenient than using charAt, StringBuilder, etc.
Like many of the other answers, valid only for the 26 letters that also occur in ASCII.
class Foo {
public static String upcase(String str) {
char[] arr = str.toCharArray();
for (int k=0; k<arr.length; k++) {
if (arr[k] >= 'a' && arr[k] <= 'z') {
arr[k] -= ('a'-'A');
}
}
return new String(arr);
}
public static void main(String... args) {
String test = "a9z A?Z";
System.out.println(test + " ==> " + upcase(test));
}
}
So I'm writing a program that mimics a phone keypad, whereas it would convert a string of text to integers: abc(2), def(3), ghi(4), jkl(5), mno(6), pqrs(7), tuv(8), wxyz(9). Except the output should have hyphens(-) between the digits.
Example input: Alabama
Output: 2-5-2-2-2-6-2
But my code only outputs 2522262. How would I go about formatting this correctly?
import java.util.Scanner;
public class PhoneKeypad {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
System.out.println(getNumbers(str));
}
private static final char[] DIGITS = (
// ABC DEF
"222" + "333"
+ // GHI JKL MNO
"444" + "555" + "666"
+ // PQRS TUV WXYZ
"7777" + "888" + "9999").toCharArray();
public static String getNumbers(CharSequence s) {
StringBuilder result = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++) {
char c = Character.toUpperCase(s.charAt(i));
if ('A' <= c && c <= 'Z') {
result.append(DIGITS[c - 'A']);
}
}
}
Add the - after each digit. Easiest way I see, change
result.append(DIGITS[c - 'A']);
to
result.append(DIGITS[c - 'A']).append('-');
Then remove the last - when you return like,
public static String getNumbers(CharSequence s) {
StringBuilder result = new StringBuilder(s.length() * 2); // <-- digit-digit...
for (int i = 0; i < s.length(); i++) {
char c = Character.toUpperCase(s.charAt(i));
if ('A' <= c && c <= 'Z') {
result.append(DIGITS[c - 'A']).append('-');
}
}
if (result.length() > 1) {
result.setLength(result.length() - 1);
}
return result.toString(); // <-- Don't forget to return the result.
}
You might find it easier if you pass in s, you could call toUpperCase() and toCharArray() and then use a for-each loop. Like,
public static String getNumbers(String s) {
StringBuilder result = new StringBuilder(s.length() * 2);
for (char c : s.toUpperCase().toCharArray()) {
if (c >= 'A' && c <= 'Z') { // <-- I find this test easier to read,
// but that's just my opinion.
result.append(DIGITS[c - 'A']).append('-');
}
}
if (result.length() > 1) {
result.setLength(result.length() - 1);
}
return result.toString();
}
I'm a beginner at java and can't get this code to work. What I have to do is convert any inputted string to uppercase without using the toUpperCase string method. This is what I have:
public String toUpperCase(String str)
{
for(int i = 0; i < str.length(); i++)
{
char a = str.charAt(i);
a = Character.toUpperCase(a);
str += Character.toString(a);
}
return str;
}
You are using str as input, and output (so your String has infinite length, as you keep adding characters). And you can use static, because you aren't using instance state. And, you might use a for-each loop. Finally, add another String, or better a StringBuilder like
public static String toUpperCase(String str) {
StringBuilder sb = new StringBuilder();
for (char ch : str.toCharArray()) {
sb.append(Character.toUpperCase(ch));
}
return sb.toString();
}
There is the following way, but it doesn't consider any characters outside of English (no diacritics, no other languageās characters behind a-z).
public String toUpperCase(String str) {
char[] chars = str.toCharArray();
for (int i=0; i<chars.length; i++) {
char c = chars[i];
if ('a' <= c && c <= 'z') {
chars[i] = (char) (c - 'a' + 'A');
}
}
return new String(chars);
}
I am aware your school probably do not allow you to use StringBuilder and in case you can't use array as well. This is another primitive approach which your school may accept:
public static String toUpperCase(String s){
String str = "";
for(int x=0; x<s.length(); x++){
char ch = s.charAt(x);
if(ch >= 'a' && ch <= 'z')
str += "" + (char)(ch - 32);
else
str += "" + ch;
}
return str;
}
Test:
System.out.println(toUpperCase("aAbBcC"));
Output:
AABBCC
Since you can't use the toUpperCase() method, you can use the ASCII table to get from a lower case letter to an upper case letter by subtracting 32.
'a' = 97, 'A' = 65
'b' = 98, 'B' = 66
...
'z' = 122, 'Z' = 90
public static int DIFF = 'a' - 'A'; // 32
public static String toUpperCase(String str) {
StringBuilder sb = new StringBuilder();
for (char c : str.toCharArray()) {
if (Character.isLowerCase(c)) {
sb.append(String.valueOf((char)(c - DIFF)));
} else {
sb.append(c);
}
}
return sb.toString();
}
try it:
public static String toUpperCase(String str) {
String result = "";
for (int i = 0; i < str.length(); i++) {
int v = str.charAt(i);
if (v > 96 && v < 123) {
v -= 32;
}
result+=(char)v;
}
return result;
}
C'mon guys, Java 8 has been out for years!
/**
* Converts an all-lowercase String to
* uppercase. Retains only spaces, any
* other characters will be lost.
*/
public static String toUpperCase(String s) {
int diff = 'a' - 'A'; // 32
return s.chars()
.filter(c -> c >= 'a' && c <= 'z' || c == ' ')
.mapToObj(c -> String.valueOf((char) (c - (diff))))
.collect(Collectors.joining());
}
I have this code that is supposed to do what the title said, reverse the order of characters without changing the order of the words:
package stackTests;
import java.util.Scanner;
import java.util.Stack;
public class StackTest
{
Stack<Character> stack;
public StackTest()
{
stack = new Stack<Character>();
}
public String reverseString(String str)
{
int start = 0;
int start2 = 0;
int size;
char space = ' ';
char[] cArr;
Scanner scan = new Scanner(str);
cArr = str.toCharArray();
for (; start < cArr.length; start++)
{
if(cArr[start] == space || start == cArr.length - 1)
{
for (; start2 < stack.size(); start++)
{
System.out.print(stack.pop());
}
}
else
{
stack.push(cArr[start]);
}
start2 = 0;
}
return str;
}
}
It works fine if I enter a single word like "Hello"--it will output "olleH"--but as soon as it gets more complicated than one word it starts to output some weird things."Hello my name is" outputs "ollehem". I'm really new to Stacks and this is my first time using them. I'm not sure if there is a logic error or improper use of Stacks.
you're not outputting original spaces, this is why you're seeing strange results
here is fixed version:
public static void reverseString(final String str) {
final Stack<Character> stack = new Stack<>();
for (int i = 0; i < str.length(); i++) {
final char c = str.charAt(i);
if (c == ' ') {
while (!stack.isEmpty())
System.out.print(stack.pop());
System.out.print(' ');
} else
stack.push(c);
}
while (!stack.isEmpty())
System.out.print(stack.pop());
}
another version without stack, with in-place replacement:
public static void reverseString(final String str) {
final char[] chars = str.toCharArray();
int start = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == ' ') {
reverse(chars, start, i - 1);
start = i + 1;
}
}
reverse(chars, start, chars.length - 1);
System.out.println(new String(chars));
}
private static void reverse(final char[] chars, int s, int e) {
while (s < e) {
final char t = chars[s];
chars[s] = chars[e];
chars[e] = t;
s++;
e--;
}
}
If you HAVE to use a stack, I would follow an algorithm like this:
String myString = "Hello World";
Stack<Character> stack = new Stack<Character>();
StringBuilder sb = new StringBuilder();
String[] splitString = myString.split(" ");
//Iterate through each word in the string
for(String s : splitString){
//Push each character of the word into LIFO stack
for(char c : s.toCharArray()){
stack.push(c);
}
//Build new string with reverse ordered characters
while(!stack.isEmpty()){
sb.append(stack.pop());
}
//Append a space as long as it's not the last word of the original string
if(!s.equals(splitString[splitString.length - 1]))
sb.append(" ");
}
//Print the new string
System.out.println(sb.toString());
I'm not sure efficiency matters to you, but this algorithm would work in linear time, where n is the number of characters in the string.
Here is how you can do it in-place without using any extra space (Not using stack):
public class ReverseWordsInplace {
public static void main(String[] args) {
reverseWords(new StringBuilder("This is a test"));
}
public static void reverseWords(StringBuilder s) {
StringBuilder str = new StringBuilder(s);
int startWordIndex = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ' ' || str.length() - 1 == i) {
int x = 0;
int endWordIndex = str.charAt(i) == ' ' ? i - 1 : i;
while (endWordIndex - x > startWordIndex + x) {
char c1 = str.charAt(startWordIndex + x);
char c2 = str.charAt(endWordIndex - x);
str.setCharAt(startWordIndex + x, c2);
str.setCharAt(endWordIndex - x, c1);
x++;
}
startWordIndex = i + 1;
}
}
System.out.println(str);
}
}
Output:
sihT si a tset