I have an array that prints out the number with a comma attached but for the last iteration, I don't want there to be a comma attached to the last number. Is there a way that I can create an if statement that only applies to the last iteration? Its java.
There are often much better ways depending on your language.
In Java 8 you should be able to use String.join(", ", listOfItems)
There are a few other Join methods that work the same way in older versions of Java but I always have trouble finding them.
In Groovy and Ruby I believe all the collections have join methods that work like this:
assert "this is a test".split(" ").join(", ") == "this, is, a, test"
Just print the , before the item and don't do it for the first one. You didn't mention the language but Java/C/C#/Javascript solution would be something like:
for (int x = 0; x < ListSize; x++)
{
if (i > 0)
{
print ",";
}
print list[i];
}
you can check on the last item of the array in most languages. Though, it seems your issue is probably a design and not syntax issue.
Any how, here is an example in javascript
var ar = ['1', '2', '3', '4', '5'];
for (var i = 0; i < ar.length; i++) {
if (i == ar.length - 1) {
console.log(ar[i]);
} else {
console.log(ar[i] + ',');
}
}
create a string by iterating and appending comma, and then do substring. "1,2,3,".substring(0,L-1) where L is length.
Related
I am new to Java and am trying to make a program that will take a string 'names' and replace the names of the people mentioned in that string with a nickname from another string 'replacement'. For instance, "John and Robert were on the way to meet Elizabeth" should return "Joe and Bob were on the way to meet Liz".
My issue is that whenever I run my program, I get multiple sentences back with only one name replaced in each (I'm guessing it is creating a new string each time). Is there a way to avoid this and have it all printed in one sentence? Could I use regex on 'replacement' somehow to fix it?
public static string namereplacer(String names, String replacement) {
String[] toreplace = replacement.split("\t|\n");
for (int i = 0; i <= toreplace.length/2; i++) {
if (i % 2 == 0) { //take even values
fixed; += names.replaceAll(toreplace[i+1],toreplace[i]);
}
}
return fixed;
}
public static void main (String[] args) {
namereplacer("John and Robert were on the way to meet Elizabeth", "John\tJoe\nRobert\tBob\nElizabeth\tLiz");
}
I couldn't run the code you have submitted because the variable fixed isn't declared and i suspect the line
fixed; += names.replaceAll(toreplace[i+1],toreplace[i]);
is supposed to be
fixed += names.replaceAll(toreplace[i+1],toreplace[i]);
because that would somewhat explain why you are getting multiple sentences, since you are replacing things multiple times and adding the result to fixed.
That being said I have noticed that when you are replacing the names with
names.replaceAll(toreplace[i+1],toreplace[i]); you should be doing
names.replaceAll(toreplace[i],toreplace[i+1]); since you would like to replace John for Joe, Robert for Bob and Elizabeth for Liz, not the other way around (Joe for John). Basically you want to replace the "even" with the "odd" so if you are selecting the even values of i you you like to replace those with i+1.
Also when iterating the array in the for loop with
for (int i = 0; i <= toreplace.length/2; i++)
you should be doing
for (int i = 0; i <= toreplace.length; i++)
because you want all the "evens" not just half of them, i think you might have switched up yourself a bit here with the evens logic and replacing half...
So to make your code work like you intend to you should replace the following lines:
for (int i = 0; i <= toreplace.length/2; i++) for
for (int i = 0; i <= toreplace.length; i++)
fixed; += names.replaceAll(toreplace[i+1],toreplace[i]); for
fixed = fixed.replaceAll(toreplace[i+1],toreplace[i]);
and also define the variable fixed beforehand Sting fixed = names; so that it has the same value as names.
Furthermore you can also improve your code a little bit:
A for is constituted by three statements for(statement1; statement2; stament3)
statement1 is executed a single time before the code block (what's inside the for)
statement2 defines the condition for executing the code block, the for will run while this statement is true
statement3 is executed everytime after the code block has been executed by the for loop
Generaly you will find and write foor loops like for(i=0; i!=foo; i++) where statement1 is used for variable initialization, statement2 for condition and statement3 for increment, but that doens't mean it is all you can do with it, in reality you can write whatever you want/need in those statements.
In you case you have
for (int i = 0; i <= toreplace.length/2; i++) {
if (i % 2 == 0) { //take even values
fixed; += names.replaceAll(toreplace[i+1],toreplace[i]);
}
}
This means you are iterating over the toreplace array, taking the "evens" and replacing them with the "odds" on the fixed string, however inside the for loop you are selecting only half of the iterations you are making with if (i % 2 == 0) and you don't really need to do that since you can just choose to iterate by 2 instead of iterating all of them and only selecting half of them to do the replacement.
To do this you simply declare for (int i = 0; i != toreplace.length; i+=2) or the long way i=i+2 if you prefer, and you no longer need the if statement because you know you will be iteraing over all the even numbers.
Hope this helped you in some way.
Change the method namereplacer to this
public static String namereplacer(String names, String replacement) {
String[] toreplace = replacement.split("\n");
for(String str: toreplace){
String [] keyValue = str.split("\t");
if(keyValue.length != 2)
continue;
names = names.replaceAll(keyValue[0], keyValue[1]);
}
return names;
}
I have two lists of words,
A: pit pot spate slaptwo respite,
B: pt Pot peat part
I have to create a regex Pattern that returns true for everything in column A and false for everything in column B. I think there is something I'm fundamentally missunderstanding about regex, because everything I come up with ends up with having one extra false where I don't want it. Mainly I can't seen to figure out how to disallow two vowels next to each other.
Here's what I have:
public static void main(String[] args){
String[] check = {"pit","spot","spate","slaptwo","respite","pt","Pot","peat","part"};
Pattern p = Pattern.compile("([psr][^t(ea)][^r])\\w*");
ArrayList<Matcher> M = new ArrayList<Matcher>();
for (int i = 0; i < check.length; i++) {
M.add(p.matcher(check[i]));
}
for (int j = 0; j < M.size(); j++){
System.out.println("Return Value:" +check[j] + "\t"+ M.get(j).matches());
}
}
I understand now that (ea) is not being read as one thing so it causes respite to be false when I don't want it to, everything else returns the correct value. As I said before I need to know how to disallow two vowels being next to each other. Or if I am just missing something fundamental here?
You cannot use grouping constructs inside of a character class.
To disallow "ea" you can use Negative Lookahead here.
[psr](?!ea)[^t][^r]\\w*
Live Demo
I want to print my name's letters one by one like so:
Result:
A
Af
Afs
afsh
afsha
afshan
.....
I've tried this coding but its a simple loop and it showing my complete name.
char[]aar={'a','f','s','h','a','n'};
for(int b=0; b<1;b++){
String str=new String(aar);
System.out.println(""+str);
}
It's simple. You can use the substring method of String class.
String name="yourname";
for(int i=0;i<name.length();i++)
{
System.out.println(name.substring(0,i+1));
}
It sounds like you want to print a substring of your name on each step. So start with the complete name:
String name = "Afshan";
and then loop for as many letters as there are (using String.length() to check) and then print the substring from the start to that iteration number - use name.substring(0, i + 1) to get the relevant substring where i is the variable in the loop. Read the documentation for substring carefully to see what each of the parameters means (and why you want i + 1 rather than i).
It's important to use i in the body of the loop, otherwise you will be printing the same thing on each iteration.
I won't provide the full code here, as you're trying to learn (yay) but as an aside, try to avoid using "" + ... - in your existing code, you don't need it anyway, as str is already a string, but if you do need to convert a different type into a string, use String.valueOf(x) instead. That says exactly what you want to do, whereas concatenation with an empty string doesn't.
Here's another way using nested for-loops
char[]aar={'a','f','s','h','a','n'};
//count just from 1 to the length of array
for(int a = 1; a<aar.length; a++)
{
//print elements from 0-1, 0-2 ,0-3, and so on.
for(int b=0; b<a;b++)
{
System.out.print(aar[b]);
}
System.out.println();
}
Here is an another version.
Please use meaningful names and correct indentation.
Note that the outer for loop needs the equals. Otherwise it doesn't work.
char[] chars = {'a', 'f', 's', 'h', 'a', 'n'};
for (int length = 1; length <= chars.length; length++) {
for(int i = 0; i < length; i++) {
System.out.print(chars[i]);
}
System.out.println();
}
The question is about while-loops in which I need some code to be executed N times and some other code N+1 times. NOT about concatening Strings, I just use this as bad-coded yet short example.
Let me explain my question by providing an example.
Say I want to concatenate N+1 Strings, by glueing them with "\n", for example. I will have N+1 lines of text then, but I only need to add N times "\n".
Is there any boilerplate solution for this type of loop in which you have to execute some code N times and other code N+1 times? I'm NOT asking for solution to concatenate Strings! That is just a (bad) example. I'm looking for the general solution.
The problem I have with this is code duplication, so to code my example I'll do this (bad pseudo code, I know I have to use StringBuilder etc.):
String[] lines = <some array of dimension N+1>;
String total = lines[0];
for (int i = 1; i < N + 1; i++){
total += "\n" + lines[i];
}
The problem becomes worse if the code that has to be executed N+1 times, becomes larger, of course. Then I would do something like
codeA(); // adding the line of text
for (int i = 1; i < N + 1; i++){
codeB(); // adding the "\n"
codeA();
}
To remove the duplication, you can do this different by checking inside the loop, too, but then I find this quite stupid as I know beforehand that the check is pre-determined, as it will only be false the first iteration:
for (int i = 0; i < N + 1; i++){
if (i > 0){
codeB(); // adding the "\n"
}
codeA();
}
Is there any solution for this, a sort of while-loop that initializes once with codeA() en then keeps looping over codeB() and codeA()?
People must have run into this before, I guess. Just wondering if there are any beautiful solutions for this.
To my dissapointment, I believe that there is no such construct that satisfies the conditions as you have stated them and I will attempt to explain why (though I can't prove it in a strictly mathematical way).
The requirements of the problem are:
We have two parts of code: codeA() and codeB()
The two parts are executed a different number of times, N and N+1
We want to avoid adding a condition inside the loop
We want to execute each part only as many times as strictly necessary
2) is a direct consequence of 1). If we didn't have two parts of code we would not need a different number of executions. We would have a single loop body.
4) is again a consequence of 1). There is no redundant execution if we have a single loop body. We can control its execution through the loop's condition
So the restrictions are basically 1) and 3).
Now inside the loop we need to answer two questions on each iteration: a) do we execute codeA()? and b) do we execute codeB()? We simply do not have enough information to decide since we only have a single condition (the condition of the loop) and that condition will be used to decide if both of the code parts would be executed or not.
So we need to break 1) and/or 3) Either we add the extra condition inside the loop or we delegate the decision to some other code (thus not having two parts anymore).
Apparently an example of delegation could be (I am using the string concatenation example):
String [] lines = ...
for (int i = 0; i < N; i++){
// delegate to a utility class LineBuilder (perhaps an extension of StringBuilder) to concatenate lines
// this class would still need to check a condition e.g. for the first line to skip the "\n"
// since we have delegated the decisions we do not have two code parts inside the loop
lineBuilder.addLine( lines[i] );
}
Now a more interesting case of delegation would be if we could delegate the decision to the data itself (this might worth keeping in mind). Example:
List<Line> lines = Arrays.asList(
new FirstLine("Every"), // note this class is different
new Line("word"),
new Line("on"),
new Line("separate"),
new Line("line") );
StringBuffer sb = new StringBuffer();
for (Line l : lines) {
// Again the decision is delegated. Data knows how to print itself
// Line would return: "\n" + s
// FirstLine would return: s
sb.append( l.getPrintVersion() );
}
Of course all of the above does not mean that you couldn't implement a class that tries to solve the problem. I believe though this is beyond the scope of your original question not to mention that would be an overkill for simple loops
Concatenating Strings like this is a bad idea and a much bigger issue IMHO.
However to answer your question I would do
String sep = "";
StringBuilder sb= new StringBuilder();
for(String s: lines) {
sb.append(sep).append(s);
sep = "\n";
}
String all = sb.toString();
Note: there is usually a good way to avoid needing to create this String at all such a processing the lines as you get them. It is hard to say without more context.
This kind of thing is fairly common, like when you build sql. This is the pattern that I follow:
String[] lines ...//init somehow;
String total = lines[0];
boolean firstTime = true;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++){
if(firstTime) firstTime = false;
else sb.append('\n');
sb.append(lines[i]);
}
Note that this is not the same, as the first example and here is why:
String[] lines = <some array of dimension N+1>;
String total = lines[0];
for (int i = 1; i < N + 1; i++){
total += "\n" + lines[i];
}
Assuming you have an array of [0] = 'line1' and [1] = 'line2'
Here you end up with line1line2\n, when the desired output is:
line1\nline2.
The example I provided is clear, and does not perform poorly. In fact a much bigger performance gain is made by utilizing StringBuilder/Buffer. Having clear code is essential for the pro.
Personally i have most of the time the same problem, on the String example i use the StringBuilder as you said, and just delete the characters added to much:
StringBuilder sb = new StringBuilder();
for(int i=0; i<N; i++) {
sb.append(array[i]).append("\n");
}
sb.delete(sb.length-1, sb.length); // maybe check if sb contains something
In the common case i suppose there is no other way than adding the if you suggested. To make the code more clear i would check at the end of the for loop:
StringBuilder sb = new StringBuilder();
for(int i=0; i<N; i++) {
sb.append(array[i]);
if(i < N) {
sb.append("\n");
}
}
But i totally agree this is sad to have this double logic
Another problem I try to solve (NOTE this is not a homework but what popped into my head), I'm trying to improve my problem-solving skills in Java. I want to display this:
Students ID #
Carol McKane 920 11
James Eriol 154 10
Elainee Black 462 12
What I want to do is on the 3rd column, display the number of characters without counting the spaces. Give me some tips to do this. Or point me to Java's robust APIs, cause I'm not yet that familiar with Java's string APIs. Thanks.
It sounds like you just want something like:
public static int countNonSpaces(String text) {
int count = 0;
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) != ' ') {
count++;
}
}
return count;
}
You may want to modify this to use Character.isWhitespace instead of only checking for ' '. Also note that this will count pairs outside the Basic Multilingual Plane as two characters. Whether that will be a problem for you or not depends on your use case...
Think of solving a problem and presenting the answer as two very different steps. I won't help you with the presentation in a table, but to count the number of characters in a String (without spaces) you can use this:
String name = "Carol McKane";
int numberOfCharacters = name.replaceAll("\\s", "").length();
The regular expression \\s matches all whitespace characters in the name string, and replaces them with "", or nothing.
Probably the shortest and easiest way:
String[][] students = { { "Carol McKane", "James Eriol", "Elainee Black" }, { "920", "154", "462" } };
for (int i = 0 ; i < students[0].length; i++) {
System.out.println(students[0][i] + "\t" + students[1][i] + "\t" + students[0][i].replace( " ", "" ).length() );
}
replace(), replaces each substring (" ") of your string and removes it from the result returned, from this temporal string, without spaces, you can get the length by calling length() on it...
The String name will remain unchanged.
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
cheers
To learn more about it you should watch the API documentation for String and Character
Here some examples how to do:
// variation 1
int count1 = 0;
for (char character : text.toCharArray()) {
if (Character.isLetter(character)) {
count1++;
}
}
This uses a special short from of "for" instruction. Here's the long form for better understanding:
// variation 2
int count2 = 0;
for (int i = 0; i < text.length(); i++) {
char character = text.charAt(i);
if (Character.isLetter(character)) {
count2++;
}
}
BTW, removing whitespaces via replace method is not a good coding style to me and not quite helpful for understanding how string class works.