I am trying to return a string pulled from the 2nd element of a given array inside of an ArrayDeque
I tried casting it and toString and concatenation after ToArray but I get this... I need to return it as a String
"The type of the expression must be an array type but it resolved to String"
ArrayDeque<String[]> bindings_and_var = new ArrayDeque();
public ArrayDeque<String[]> pushBindings(String var, String bindings) {
//var first element, bindings 2nd
String[] this_bindings_and_var = new String[2];
bindings_and_var.addLast(this_bindings_and_var);
return bindings_and_var;
}
public ArrayDeque<String[]> bindingsVal() {
return bindings_and_var;
}
public String lookup(int index) {
String[] array = (String[]) bindings_and_var.toArray();
//PROBLEM AREA vvv
String s = "" + array[index][1];
return s;
Your lookup method should look like this:
public String lookup(int index)
{
int counter = 0;
for (Iterator<String[]> itr = bindings_and_var.iterator(); itr.hasNext();)
{
String[] t = itr.next();
if (counter == index)
{
return t[1];
}
counter++;
}
}
You have defined your Deque as String[] while when you are doing bindings_and_var.toArray(); you would receive object array with each object as String array. Try,
Object[] array = (String[]) bindings_and_var.toArray();
Object obj = array[index];
String[] myArray = (String[])obj;
String s = "" + myArray[1];
Or
int i = 0;
for (String[] s : bindings_and_var) {
if (i == index) {
return s[1];
}
i++;
}
so that you don't have to iterate the whole collection.
Related
Code logic
In order to find all subsequences of String s that are equal to String t, I made a recursive method getSub() to get all the subsequences of input string s and added it to the list. Now I loop through the list (in numDistinct method) and try to see all those subsequences in the list that matches the string t. In case there is a match count should be incremented and later returned.
BUT
Question
In the following code count never increases, which means the if condition (in numDistinct method) does not work as it was intended. Why t which is a string and list.get(i) which should also return a string doesn't seem to work with equals method?
public static int numDistinct(String s, String t) {
int count = 0;
ArrayList<String> list = new ArrayList<>();
getSub(s, list);
StdOut.println(list);
for (int i = 0; i < list.size(); i++) {
if (t.equals(list.get(i))) {
count++;
}
}
return count;
}
private static int getSub(String s, ArrayList<String> list) {
if (s.length() == 0) {
list.add(" ");
return 1;
}
int smallOutput = getSub(s.substring(1), list);
char[] cha = s.toCharArray();
for (int i = 0; i < smallOutput; i++) {
list.add(cha[0] + list.get(i));
}
return 2 * smallOutput;
}
public static void main(String[] args) {
String s = "rabbbit";
String t = "rabbit";
StdOut.println(numDistinct(s, t));
}
The way you are creating the strings in the list ensures there is a space character at the end of each string. As such, none of them are equal to t.
if (s.length() == 0) {
list.add(""); // remove the space from this line
return 1;
}
So what I am trying to do is take the list I have and start at the end. From there I need to go backwards and return the list as a String. So my array has "Words are flowing out like endless rain into a paper cup". I'm trying to make them cuppaperainto... and so on. This is my code but it is giving me a symbol not found error on my list.size and list.listIterator. Just wondering what I'm doing wrong and how to fix this problem.
public class LabListIterators {
public static void main(String[] args) {
List<String> list = new LinkedList<String>();
// Add items to the List
String [] array = {"Words", "are", "flowing", "out", "like", "endless", "rain", "into", "a", "paper", "cup"};
for (int i = 0; i < array.length; ++i)
list.add (array[i]);
System.out.println(list + ", size = " + list.size());
capitalize(list);
System.out.println(list);
System.out.println(concatenateBackwards(list));
}
public static String concatenateBackwards(List<String> words)
{
ListIterator iter = list.listIterator(list.size());
while (iter.hasPrevious())
{
String str = iter.previous() + str;
}
return str;
}
}
You just got the names and the scope mixed up a little from this code block
public static String concatenateBackwards(List<String> words)
{
ListIterator iter = list.listIterator(list.size());
while (iter.hasPrevious())
{
String str = iter.previous() + str;
}
return str;
}
The method takes in List<String> words but you are trying to call listIterator() on a object list which I think you wanted to use when you created within the main() method.
Inside the while loop:
String str = iter.previous() + str;
You have to declare str first before you can use it. So move the str declaration before the while loop. Also, the return str; does not know about the scope of tr because it is declared within the while loop body.
Solution:
public static String concatenateBackwards(List<String> words)
{
String str = "";
ListIterator iter = words.listIterator(list.size());
while (iter.hasPrevious())
{
str += iter.previous();
}
return str;
}
You are declaring the String inside the loop
while (iter.hasPrevious())
{
String str = iter.previous() + str;
}
return str;
Try
String str ="";
while (iter.hasPrevious())
{
str = iter.previous() + str;
}
return str;
My code is supposed to separate a given String and covert the chosen letters into # and separate and concatenate the words with the chosen letter. My problem is with one of the methods (allWordsWith) in my code, it won't allow me to return a String array. (p.s, the codes that run this one are irrelevant, I'm not supposed to edit those).
import java.util.Arrays;
import java.util.Scanner;
public class LipogramAnalyzer {
private String line;
public LipogramAnalyzer(String text){
line = text;
}
public String mark (char letter){
String replaceletters = line.replace(letter, '#');
return replaceletters;
}
public String[] allWordsWith (char letter){
String[] arr = line.split(" ");
for ( String ss : arr) {
String ary[] = {ss};
for(int i = 0; i < ary.length; i++){
int numindex = ss.indexOf(letter);
if (numindex != -1){
String result = ary[i];
return result;
}
}
}
}
}
"It won't allow me to return a String array"
Sure it will. You're attempting to return a String:
String result = ary[i];
return result;
Even though the return type is a string array:
public String[] allWordsWith (char letter){
You need to return an array, as allWordsWith implies you want multiple values.
But the bigger problem is that you are initializing the result array to a single element
String ary[] = {ss};
and thes lengths of arrays can't be changed after initialization. This means that ary.length in this loop
for(int i = 0; i < ary.length; i++){
will always equal one. That is not what you want.
In addition, you are searching the strings in the result array (ary), even though you just created it, meaning it has nothing in it--that is, all the values are null.
If you want a list of all the strings in line that have the letter in it, try
public String[] allWordsWith (char letter){
String[] asAllWordsInLine = line.split(" ");
java.util.ArrayList<String> alsAllWordsWithChar = new java.util.ArrayList<String>();
for ( String ss : asAllWordsInLine) {
if(ss.indexOf(letter) != -1) {
alsAllWordsWithChar.add(ss);
continue; //No need to check any more letters.
}
}
return alsAllWordsWithChar.toArray(new String[alsAllWordsWithChar.size()]);
}
I've changed the array to a list, since you can't know how many strings will have letter in it. A list can change size, an array can't. When no strings match, this returns an empty array, which is preferred over null. (more info)
I've also made the variable names more meaningful, and stopped checking a word after it matches a character (with continue, which short-circuits the current for-loop iteration).
Finally, the function is not returning anything until all strings have been analyzed, meaning after the for-loop completes. In your original code the return is inside the loop, meaning only the first string is returned.
A useful testing function:
public static final void main(String[] igno_red) {
testLine('b', "abc def ghi cba def ghi");
}
private static final void testLine(char c_letter, String s_line) {
System.out.println("Line: \"" + s_line + "\"");
String[] asAllWordsWith = (new LipogramAnalyzer(s_line)).allWordsWith(c_letter);
System.out.println("Words with '" + c_letter + "': " + Arrays.toString(asAllWordsWith));
}
Return the ary not ary[i]
for(int i = 0; i < ary.length; i++){
int numindex = ss.indexOf(letter);
if (numindex != -1){
String result = ary[i];
/*here*/ return ary;
}
You can return an array. Try return ary instead of return ary[i].
Also, your function must return something in all cases. In other words, you have to have a return statement after your for loops.
public String[] allWordsWith (char letter){
String[] arr = line.split(" ");
for ( String ss : arr) {
String ary[] = {ss};
for(int i = 0; i < ary.length; i++){
int numindex = ss.indexOf(letter);
if (numindex != -1){
String result = ary[i];
// or here return ary;
}
}
}
return ary;
}
Return the array
You are trying to return a String instead of String[] (String array)
Change the code:
if (numindex != -1) {
String result = ary[i];
return result;
}
To:
if (numindex != -1) {
return new String[]{ary[i]};
}
// afrer first for loop
return arr;
If you want to return a complete String-Array at once, I have modified your function (not tested):
public String[] allWordsWith (char letter){
String[] arr = line.split(" ");
String[] result = new String[ary.length];
for ( String ss : arr) {
String ary[] = {ss};
for(int i = 0; i < ary.length; i++){
int numindex = ss.indexOf(letter);
if (numindex != -1){
result[i] = ary[i];
}
}
}
return result;
}
As already said, you're returning a String instead of a String[]. Also note that your code will only ever return a single "word". I modified your code to add every word that contains your character and add it to a List. At the end of the loop the List is converted to a String[].
public String[] allWordsWith(char letter)
{
String[] arr = line.split(" ");
List<String> result = new ArrayList<>();
for (String ss : arr) {
int numindex = ss.indexOf(letter);
if (numindex != -1) {
result.add(ss);
}
}
return result.toArray(new String[result.size()]);
}
Suppose this:
String s0 = "01234";
String[] S1 = {"jkl","abc","xyz"};
String[] S2 = {"OPQ","ghi","STU"};
String s3 = "56789";
get_AllStrings(s3, S1, S2, s0);
The returned String[] must be:
String[] NewArray = {"56789","OPQ","ghi","STU","01234"}
I want to obtain this strings like only one array of strings...
Here my method:
public String[] get_AllStrings(String... argString) { //Only String or String[]
int TheSize = 0;
for (int i = 0; i<argString.length; i++) {
if(argString[i]!= null && argString[i].getClass().isArray()) {
String[] OneArray = (String [])argString[i];
TheSize += OneArray.length;
} else {
TheSize += 1;
}
}
String[] NewArray = new String[TheSize];
int ThePos = 0;
for (int i = 0; i<argString.length; i++) {
if(argString[i]!= null && argString[i].getClass().isArray()) {
String[] OneArray = argString[i];
System.arraycopy(OneArray, 0, NewArray, ThePos, OneArray.length);
ThePos += OneArray.length;
} else {
String[] OneArray = {argString[i]};
System.arraycopy(OneArray, 0, NewArray, ThePos, 1);
ThePos += OneArray.length;
}
}
return NewArray;
}
But, is not working...
What you want to do is to use an ArrayList instead of an array.
public static String[] getAllStrings(Object ... argString) {
ArrayList<String> list = new ArrayList<String>();
for (Object stringOrArray : argString) {
if (stringOrArray instanceof String)
list.add((String) stringOrArray);
else {
String[] strings = (String) stringOrArray;
list.addAll(Arrays.asList(strings));
}
}
return list.toArray(new String[list.size()]);
}
I changed your code a bit and got this:
public static String[] get_AllStrings(Object... argString) {
ArrayList<String> strings = new ArrayList<String>();
for (int i = 0; i<argString.length; i++) {
if(argString[i]!= null && argString[i].getClass().isArray()) {
String[] OneArray = (String [])argString[i];
for(String str : OneArray)
strings.add(str);
} else {
strings.add((String)argString[i]);
}
}
return (String[])strings.toArray();
}
I could not get it to accept both String and String[] with your method signature, but a change to Object... did the trick. You can use an ArrayList to create the array directly instead of looping through everything twice.
unfortunately, you're running up against Java's type system here.
String and String[] are not subtypes.
so a variable, or array can only hold one or the other.
Using object, as done by #Johan Henriksson throws away any type safety assurances from the compiler, since any object can be put in the array. this is okay if you have some garuantee that you'll only ever have Strings, and you'll need to cast to string on pulling out of the collection.
I'm not sure exactly what you're trying to achieve here
So I'm not sure how to go about resolving this.
if you just want all the strings from all sources in a collection of some sort, I'd use a list
it's unclear where you're getting these strings and string arrays from however.
You can't pass a String[] into an element of a varargs String... parameter.
The only way to accept either String or String[] is a "typeless" varargs Object..., because Object is the only common type to both.
public static String[] get_AllStrings(Object... args) {
ArrayList<String> result = new ArrayList<String>();
for (Object o : args) {
if (o instanceof String) {
result.add((String)o);
} else if (o instanceof String[]) {
result.addAll(Arrays.asList((String[])o));
} else {
throw new IllegalArgumentException();
}
}
return (String[])result.toArray();
}
I have an array of strings, and I want to delete a particular string from that array. How can I do that? My code is:
private void nregexp(){
String str_nregexp = i_exp_nregexp.getText();
boolean b;
for(int i=0; i<selectedLocations.length; i++){
b= selectedLocations[i].indexOf(str_nregexp) > 0;
if(b){
String i_matches = selectedLocations[i];
........
........
}
}
}
I have to remove i_matches from selectedLocations.
I depends what you mean by "delete a particular String from an array". If you wish to remove its value, you can simply set its value to null, however if you mean actually remove that element from the array (you have an array of 5 elements and you want the result after deleting the element to be 4), this is not possible without copying the array with the item removed.
If you want this behavior, you might want to take a look at a dynamic list such as ArrayList or LinkedList
Edit: If you wanted a simple method to copy the array into an array with the String removed, you could do something like:
List<Foo> fooList = Arrays.asList(orgArray);
fooList.remove(itemToRemove);
Foo[] modifiedArray = fooList.toArray();
You will need to copy the array to a smaller array, omitting the string you don't want. If this is a common situation, you should consider using something other than an array, such as LinkedList or ArrayList.
If you really want to do it yourself, here is an example:
import java.util.Arrays;
public class DelStr {
public static String[] removeFirst(String[] array, String what) {
int idx = -1;
for (int i = 0; i < array.length; i++) {
String e = array[i];
if (e == what || (e != null && e.equals(what))) {
idx = i;
break;
}
}
if (idx < 0) {
return array;
}
String[] newarray = new String[array.length - 1];
System.arraycopy(array, 0, newarray, 0, idx);
System.arraycopy(array, idx + 1, newarray, idx, array.length - idx - 1);
return newarray;
}
public static void main(String[] args) {
String[] strings = { "A", "B", "C", "D" };
System.out.printf("Before: %s%n", Arrays.toString(strings));
System.out.printf("After: %s%n",
Arrays.toString(removeFirst(strings, "D")));
}
}
You cannot change the length of the array, after initializing an array its length is set. So you cannot delete the element directly, you can only replace it, also with null.
String[] arr = new String[10];
// fill array
...
// replace the fifth element with null
arr[4] = null;
If you want to change the length of the Array you should try a list instead:
List<String> list = new ArrayList<String>();
// fill list
...
// remove the fifth element
list.remove(4);
Could you show us your code? Why don't you use ArrayList, as it has a remove(index) and remove(object) support?
Edit: Perhaps
private void nregexp() {
String str_nregexp = i_exp_nregexp.getText();
boolean b;
List<String> list = new ArrayList<String>(Arrays.asList(selectedLocations));
for(Iterator<String> it = list.iterator(); i.hasNext();){
String e = it.next();
b = e.indexOf(str_nregexp) > 0;
// b = e.matches(str_regexp); // instead?
if(b){
String i_matches = s;
it.remove(); // we don't need it anymore
........
........
}
}
selectedLocations = list.toArray(new String[list.size()]);
}
I've reached this solution that allows you to remove all the elements that equal the removal element:
private static <T> T[] removeAll(T[] array, T element) {
if (null == array)
throw new IllegalArgumentException("null array");
if (null == element)
throw new IllegalArgumentException("null element");
T[] result = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length);
int j = 0;
for (int i = 0; i < array.length; i++) {
if (!element.equals(array[i]))
result[j++] = array[i];
}
return Arrays.copyOf(result, j);
}
I also did some benchmarking and this solution is definitely better then using Lists. Although, if performance is not a problem here, I would use Lists.
If you really need to remove only one element (the first) #kd304 has the solution.