How to print String - java

I have this String which I want to return but I cannot because it says that "print" cannot be resolved as a variable. This is my code:
public static String enrcyptText(String str, int shift){
int count = 0;
String[] parts = str.split("[\\W]");
for(String word : parts){
shift = shift * (count + 1) + 1;
count++;
encryptWord(word, shift);
String[] phrase = new String[]{word};
String print = String.join(" ", phrase);
}
return print;
}
any Idea?

There are several problems there.
You've declared print only within the loop body. It doesn't exist outside of it. So you need to move your String print outside the loop.
You're also assigning to it on every loop iteration, which will overwrite the previous value it had. It's unclear what you want to do instead, but you're not going to want to do that.
These two lines also don't make any sense:
String[] phrase = new String[]{word};
String print = String.join(" ", phrase);
Since there will only be one entry in phrase, you'll end up with print having the same value word had.
You seem to expect that encryptWord can modify the string passed into it. It can't.
Taking a stab at it, I'm thinking your goal is to "encrypt" individual words from a sentence, then recombine the result into a space-delimited set of encrypted words. If so, see comments:
public static String enrcyptText(String str, int shift){
int count = 0;
String[] parts = str.split("[\\W]");
// For updating the array, better to use the classic
// for loop instead of the enhanced for loop
for (int i = 0; i < parts.length; ++i){
shift = shift * (count + 1) + 1;
count++; // Could do this before previous line and remove the + 1 in (count + 1)
parts[i] = encryptWord(parts[i], shift); // See note below
}
return String.join(" ", parts);
}
Note that I'm using a return value from encryptWord. That's because strings in Java are immutable (cannot be changed), and so encryptWord can't change what we pass into it; it can only give us back a new string to use instead.

print variable has scope inside the braces.You should move the print variable outside braces to make it visible to the code.Also,since it is a local variable ,print should be initialized with a default value(in my case,it is null).The compiler will complain that print remain uninitialized(though this is not related to the main question)
public static String enrcyptText(String str, int shift){
int count = 0;
String[] parts = str.split("[\\W]");
String print = null;
for(String word : parts){
shift = shift * (count + 1) + 1;
count++;
encryptWord(word, shift);
String[] phrase = new String[]{word};
print = String.join(" ", phrase);
}
return print;
}

You have a logic error in your code: you are encrypting correctly each word but you are not building correctly the encrypted phrase. In each iteration of the loop, you are recreating the phrase when you should be adding element to the phrase array.
public static String enrcyptText(String str, int shift) {
int count = 0;
String[] parts = str.split("[\\W]");
String[] phrase = new String[parts.length]; // initialising an array containing each encrypted word
for (String word : parts) {
shift = shift * (count + 1) + 1;
count++;
String encryptedWord = encryptWord(word, shift);
phrase[count - 1] = encryptedWord; // updating the encrypted phrase array
}
return String.join(" ", phrase); // joining the phrase array
}
In this code, we are creating a phrase array before the loop. In each iteration, we update this array with the encryped word. When we have all the encrypted words, the loop terminates and we join all of the parts together.
I am also guessing that the encryptedWord actually returns the encrypted word. This method can't modify the word given as parameter.

Related

split a string when there is a change in character without a regular expression

There is a way to split a string into repeating characters using a regex function but I want to do it without using it.
for example, given a string like: "EE B" my output will be an array of strings e.g
{"EE", " ", "B"}
my approach is:
given a string I will first find the number of unique characters in a string so I know the size of the array. Then I will change the string to an array of characters. Then I will check if the next character is the same or not. if it is the same then append them together if not begin a new string.
my code so far..
String myinput = "EE B";
char[] cinput = new char[myinput.length()];
cinput = myinput.toCharArray(); //turn string to array of characters
int uniquecha = myinput.length();
for (int i = 0; i < cinput.length; i++) {
if (i != myinput.indexOf(cinput[i])) {
uniquecha--;
} //this should give me the number of unique characters
String[] returninput = new String[uniquecha];
Arrays.fill(returninput, "");
for (int i = 0; i < uniquecha; i++) {
returninput[i] = "" + myinput.charAt(i);
for (int j = 0; j < myinput.length - 1; j++) {
if (myinput.charAt(j) == myinput.charAt(j + 1)) {
returninput[j] += myinput.charAt(j + 1);
} else {
break;
}
}
} return returninput;
but there is something wrong with the second part as I cant figure out why it is not beginning a new string when the character changes.
You question says that you don't want to use regex, but I see no reason for that requirement, other than this is maybe homework. If you are open to using regex here, then there is a one line solution which splits your input string on the following pattern:
(?<=\S)(?=\s)|(?<=\s)(?=\S)
This pattern uses lookarounds to split whenever what precedes is a non whitespace character and what proceeds is a whitespace character, or vice-versa.
String input = "EE B";
String[] parts = input.split("(?<=\\S)(?=\\s)|(?<=\\s)(?=\\S)");
System.out.println(Arrays.toString(parts));
[EE, , B]
^^ a single space character in the middle
Demo
If I understood correctly, you want to split the characters in a string so that similar-consecutive characters stay together. If that's the case, here is how I would do it:
public static ArrayList<String> splitString(String str)
{
ArrayList<String> output = new ArrayList<>();
String combo = "";
//iterates through all the characters in the input
for(char c: str.toCharArray()) {
//check if the current char is equal to the last added char
if(combo.length() > 0 && c != combo.charAt(combo.length() - 1)) {
output.add(combo);
combo = "";
}
combo += c;
}
output.add(combo); //adds the last character
return output;
}
Note that instead of using an array (has a fixed size) to store the output, I used an ArrayList, which has a variable size. Also, instead of checking the next character for equality with the current one, I preferred to use the last character for that. The variable combo is used to temporarily store the characters before they go to output.
Now, here is one way to print the result following your guidelines:
public static void main(String[] args)
{
String input = "EEEE BCD DdA";
ArrayList<String> output = splitString(input);
System.out.print("[");
for(int i = 0; i < output.size(); i++) {
System.out.print("\"" + output.get(i) + "\"");
if(i != output.size()-1)
System.out.print(", ");
}
System.out.println("]");
}
The output when running the above code will be:
["EEEE", " ", "B", "C", "D", " ", "D", "d", "A"]

Performance (JAVA) ~ String concatenation in a loop with prepending and appending

I'm having performance issues. Does anyone have a faster/better solution for doing the following:
String main = "";
for (String proposition : propositions) {
if (main.length() == 0) {
main = proposition;
} else {
main = "|(" + proposition + "," + main + ")";
}
}
I know concat and stringbuilder are faster, but i don't see how i can use these methods. Because of the following line of code:
main = "|(" + proposition + "," + main + ")";
Thanks in advance!
So from what I can tell there are 3 problems here:
Values are primarily prepended to the string.
For each value a character is appended.
If only one value is present, nothing should be appended or prepended.
With 2 or more items, the 0th item is handled differently:
0:""
1:"A"
2:"|(B,A)"
3:"|(C,|(B,A))"
It can be made quicker by making a few changes:
Reverse the algorithm, this means the majority of the work involves appending, allowing you to use StringBuilders.
Count the number of closing )'s and append those after the loop is finished.
Special case for 0 or 1 items in the list.
With those changes the algorithm should be able to use a StringBuilder and be a lot quicker.
Attempt at an algorithm:
int length = propositions.size();
if (length == 0) {
main = "";
} else {
StringBuilder sb = new StringBuilder();
int nestingDepth = 0;
// Reverse loop, ignoring 0th element due to special case
for (int i = length - 1; i > 0; i--) {
sb.append("|(").append(propositions.get(i)).append(',');
nestingDepth++;
}
// Append last element due to special casing
sb.append(propositions.get(0));
for (int i = 0; i < nestingDepth; i++) {
sb.append(')');
}
main = sb.toString();
}
I believe this should produce the correct results, but it should give the right idea.
The problem is that you're prepending and appending to the string as you go. String and StringBuilder dont handle this well (and give quadratic performance). But you can use a dequeue which supports insertion at start and end to store all the pieces. Then finally you can join the bits in the dequeue.
ArrayDeque bits = new ArrayDeque();
for (String proposition : propositions) {
if (bits.size() == 0) {
bits.push(proposition);
} else {
// Add prefix
main.offerFirst("|(" + proposition + "," );
// Add suffix
main.push(")");
}
}
StringBuilder sb = new StringBuilder();
for( String s : bits) {
sb.append(s);
}
main = sb.toString();
Assuming this is an array of propositions, you could first sum the length of the String(s) in the array. Add 4 for your additional characters, and subtract 4 because you don't use those separators on the first element. That should be the perfect size for your output (this is optional, because StringBuilder is dynamically sized). Next, construct a StringBuilder. Add the first element. All subsequent elements follow the same pattern, so the loop is simplified with a traditional for. Something like,
int len = Stream.of(propositions).mapToInt(s -> s.length() + 4).sum() - 4;
StringBuilder sb = new StringBuilder(len); // <-- len is optional
sb.append(propositions[0]);
for (int i = 1; i < propositions.length; i++) {
sb.insert(0, ",").insert(0, propositions[i]).insert(0, "|(").append(")");
}
System.out.println(sb);

Copy the first N words in a string in java

I want to select the first N words of a text string.
I have tried split() and substring() to no avail.
What I want is to select the first 3 words of the following prayer and copy them to another variable.
For example if I have a string:
String greeting = "Hello this is just an example"
I want to get into the variable Z the first 3 words so that
Z = "Hello this is"
String myString = "Copying first N numbers of words to a string";
String [] arr = myString.split("\\s+");
//Splits words & assign to the arr[] ex : arr[0] -> Copying ,arr[1] -> first
int N=3; // NUMBER OF WORDS THAT YOU NEED
String nWords="";
// concatenating number of words that you required
for(int i=0; i<N ; i++){
nWords = nWords + " " + arr[i] ;
}
System.out.println(nWords);
NOTE : Here .split() function returns an array of strings computed by splitting a given string around matches of the given regular expression
so if i write the code like follows
String myString = "1234M567M98723651";
String[] arr = myString.split("M"); //idea : split the words if 'M' presents
then answers will be : 1234 and 567 where stored into an array.
This is doing by storing the split values into the given array. first split value store to arr[0], second goes to arr[1].
Later part of the code is for concatenating the required number of split words
Hope that you can get an idea from this!!!
Thank you!
public String getFirstNStrings(String str, int n) {
String[] sArr = str.split(" ");
String firstStrs = "";
for(int i = 0; i < n; i++)
firstStrs += sArr[i] + " ";
return firstStrs.trim();
}
Now getFirstNStrings("Hello this is just an example", 3); will output:
Hello this is
You could try something like:
String greeting = "Hello this is just an example";
int end = 0;
for (int i=0; i<3; i++) {
end = greeting.indexOf(' ', end) + 1;
}
String Z = greeting.substring(0, end - 1);
N.B. This assumes there are at least three space characters in your source string. Any less and this code will probably fail.
Add this in a utility class, such as Util.java
public static String getFirstNWords(String s, int n) {
if (s == null) return null;
String [] sArr = s.split("\\s+");
if (n >= sArr.length)
return s;
String firstN = "";
for (int i=0; i<n-1; i++) {
firstN += sArr[i] + " ";
}
firstN += sArr[n-1];
return firstN;
}
Usage:
Util.getFirstNWords("This will give you the first N words", 3);
---->
"This will give"
If you use Apache Commons Lang3, you can make it a little shorter like this:
public String firstNWords(String input, int numOfWords) {
String[] tokens = input.split(" ");
tokens = ArrayUtils.subarray(tokens, 0, numOfWords);
return StringUtils.join(tokens, ' ');
}
Most of the answers posted already use regular expressions which can become an overhead if we have to process a large number of strings. Even str.split(" ") uses regular expression operations internally. dave's answer is perhaps the mos efficient, but it does not handle correctly strings that have multiple spaces occurring together, beside assuming that regular space is the only word separator and that the input string has 3 or more words (an assumption he has already called out). If using Apache Commons in an option, then I would use the following code as it is not only concise and avoids using regular expression even internally but also handled gracefully input strings that have less than 3 words:
/* Splits by whitespace characters. All characters after the 3rd whitespace,
* if present in the input string, go into the 4th "word", which could really
* be a concanetation of multiple words. For the example in the question, the
* 4th "word" in the result array would be "just an example". Invoking the
* utility method with max-splits specified is slightly more efficient as it
* avoids the need to look for and split by space after the first 3 words have
* been extracted
*/
String[] words = StringUtils.split(greeting, null, 4);
String Z = StringUtils.join((String[]) ArrayUtils.subarray(words, 0, 3), ' ');

replacing characters of a string

So I'm trying to iterate over a string and replace ever occurrence of a given substring with a new value. I can't seem to figure out what the problem with my code is because it doesn't seem to make any changes to the strings i run through it.
i create a new string nS that starts out as just “”, and am iterating through the template viewing each character as a substring s. In in every case that something needs to be replaced with a value i append said value on to the nS, else it just appends the current substring as is.
#Override
public String format(String template) {
String nS = "";
for (int i = 0, n = template.length(); i < n; i++) {
String s = template.substring(i, i + 1);
switch (s) {
case "%%":
nS = nS.concat("%");
break;
case "%t":
nS = nS.concat(String.valueOf(inSeconds()));
break;
}
}
return nS;
}
the actual code has many more cases but i left them out so that its not as overwhelming.
The ending index in the 2-arg substring method is exclusive.
The substring begins at the specified beginIndex and extends to the character at index endIndex - 1.
beginIndex - the beginning index, inclusive.
endIndex - the ending index, exclusive.
You are getting a substring of exactly one character, not 2. Try i + 2, after the appropriate bounds-checking:
String s = template.substring(i, i + 2);
Assuming performance is not a big issue I would do
public String format(String template) {
return template.replaceAll ("%%", "\uffff")
.replaceAll("%t", ""+inSeconds())
.replaceAll("\uffff", "%");
}
What you're describing attempting to do sounds like you're trying to rewrite String.replace()
Given String s = "My Name Is Bob"
and you would like to replace "Bob" with "Susan" all you need to do is:
String s = "My Name is Bob";
String n = s.replace("Bob", "Susan");
System.out.println(n); //My Name is Susan
System.out.println(s); //My Name is Bob
Another option, is to break the string into a character array and iterate over it.
String s = "My Name is Bob";
char[] bits = s.toCharArray();
for(char c : bits) {
// logic
}
Compare two characters at once:
String s = "My Name is Bob";
char[] bits = s.toCharArray();
for(int i = 0; i < bits.length; i++) {
if(i + 1 <= bits.length) {
String searchFor = "" + bits[i] + bits[i + 1];
// logic
}
}

Return word specified by the integer

I know I'm missing some things and that's what I really need help with. The code doesn't work in all cases and am looking for help improving/fixing it.
Assignment:
The code I have so far:
public String word(int num, String words)
{
int l = words.indexOf(" ");
int r = words.indexOf(" ", l+1);
for(int i = 3; i <= num; i++){
l = r;
r = words.indexOf(" ", l+1);
//if(i != num)
// l = r;
}
String theword = words.substring(l,r);
return theword;
}
}
As this is clearly homework, I will give you text only.
Your approach may work eventually, but it is laborious and overly complicated, so it's hard to debug and hard to get right.
make use of String's API by using the split() method
after splitting the sentence into an array of word Strings, return the element at num less one (array are indexed starting at zero
check the length of the array first, in case there are less words than num, and take whatever action you think is appropriate in that case
For part 2, a solution in a simple form may be:
create a new blank string for the result
iterate over the characters of the given string adding the character to the front of the result string
make use of String's toUpperCase() method
Since this is homework and you have showed some effort. This is how you can do part 1 of your question. This code is pretty evident.
1) I am returning null if number is greater than the number of words in string as we dont want user to enter 5 when there are only 2 words in a string
2) Splitting the string by space and basically returning the array with the number mentioned by user
There are more conditions which you must figure out such as telling the user to enter a number of the string length since it would not give him any result and taking input from Scanner instead of directy adding input in method.
public static String word(int num, String words)
{
String wordsArr[] = words.split(" ");
if(num <= 0 || num > wordsArr.length) return null;
return (wordsArr[num-1]);
}
the second part of your question must be attempted by you.
Well... not often you see people coming here with homework AND showing effort at the same time so bravo :).
This is example of how you can split the string and return the [x] element from that string
public class SO {
public static void main(String[] args) throws Exception {
int number = 3;
String word = "Hello this is sample code";
SO words = new SO();
words.returnWord(number, word);
}
private void returnWord(int number, String word) throws Exception {
String[] words = word.split("\\s+");
int numberOfWords = words.length;
if(numberOfWords >= number) {
System.out.println(words[number-1]);
} else {
throw new Exception("Not enought words!!!");
}
}
}
Yes it is a working example but do not just copy and paste that for your homework - as simple question from teacher - What is this doing, or how this works and your out :)! So understand the code, and try to modify it in a way that you are familiar what is doing what. Also its worth getting some Java book - and i recommend Head first Java by O'Really <- v.good beginner book!
if you have any questions please do ask!. Note that this answer is not 100% with what the textbook is asking for, so you can modify this code accordingly.
As of part 2. Well what Bohemian said will also do, but there is a lot quicker solution to this.
Look at StringBuilder(); there is a method on it that will be of your interest.
To convert String so all letter are upper case you can use .toUpperCase() method on this reversed string :)
You can try:
public class trial {
public static void main(String[] args)
{
System.out.println(specificword(0, "yours faithfully kyobe"));
System.out.println(reverseString("derrick"));}
public static String specificword(int number, String word){
//split by space
String [] parts = word.split("\\ ");
if(number <= parts.length){
return parts[number];
}
else{
return "null String";
}
}
public static String reverseString(String n){
String c ="";
for(int i = n.length()-1; i>=0; i--){
char m = n.charAt(i);
c = c + m;
}
String m = c.toUpperCase();
return m;
}
}
For the first problem, I'll give you two approaches (1. is recommended):
Use the String.split method to split the words up into an array of words, where each element is a word. Instead of one string containing all of the words, such as "hello my name is Michael", it will create an array of the words, like so [hello, my, name, is, Michael] and that way you can use the array to access the words. Very easy:
public static String word(int num, String words)
{
// split words string into array by the spaces
String[] wordArray = words.split(" "); // or = words.split("\\s+");
// if the number is within the range
if (num > 0 && num <= wordArray.length) {
return wordArray[num - 1]; // return the word from the word array
} else { // the number is not within the range of words
return null;
}
}
Only use this if you cannot use arrays! Loop through the word until you have found enough spaces to match the word you want to find:
public static String word(int num, String words)
{
for (int i = 0; i < words.length(); i++) { // every character in words
if (words.substring(i, i+1).equals(" ")) { // if word is a space
num = num - 1; // you've found the next word, so subtract 1 (number of words left is remaining)
}
if (num == 1) { // found all words
// return this word
int lastIndex = i+1;
while (lastIndex < words.length()) { // until end of words string
if (words.substring(lastIndex, lastIndex+1).equals(" ")) {
break;
}
lastIndex = lastIndex + 1; // not a space so keep moving along the word
}
/*
// or you could use this to find the last index:
int lastIndex = words.indexOf(" ", i + 1); // next space after i+1
if (lastIndex == -1) { // couldn't find another space
lastIndex = words.length(); // so just make it the last letter in words
}*/
if (words.substring(i, i+1).equals(" ")) { // not the first word
return words.substring(i+1, lastIndex);
} else {
return words.substring(i, lastIndex);
}
}
}
return null; // didn't find word
}
As for the second problem, just iterate backwards through the string and add each letter to a new string. You add each letter from the original string to a new string, but just back to front. And you can use String.toUpperCase() to convert the string to upper case. Something like this:
public static String reverse(String str) {
String reversedString = ""; // this will be the reversed string
// for every character started at the END of the string
for (int i = str.length() - 1; i > -1; i--) {
// add it to the reverse string
reversedString += str.substring(i, i+1);
}
return reversedString.toUpperCase(); // return it in upper case
}

Categories

Resources