This question already has an answer here:
Groovy List<List<Integer>> behaving like List<Integer>
(1 answer)
Closed 1 year ago.
Does groovy not have matured support for generics? If I am explicitly saying I want a Map<Character, Character> will it not respect it?
The below code fails because map.get(Character) is giving me null. When I use Map<String, String> it works.
String eq = "{([])}"
Map<Character, Character> map = [ '}':'{', ')': '(', ']': '[' ]
Stack<Character> stack = new Stack();
Character[] arr = eq.toCharArray();
for (int i = 0 ; i < arr.length; i++) {
Character c = arr[i]
if (stack.isEmpty()) {
stack.push(c)
} else { // check for the end
char c1 = stack.peek()
**// map.get(c) is null here**
if (c1 == map.get(c)){
stack.pop()
} else {
stack.push(c)
}
}
}
if (stack.isEmpty()) {
println "Balanced Eq"
} else {
println "Not Balanced Eq"
}
Groovy uses ' for string literals and not for chars (like Java). "-literals allow ${} replacements, '-literals don't.
If you want those error catched, you most likely want to add TypeChecked or CompileStatic as compiler option or as annotations on the places, that depend on it. The default, "dynamic" Groovy does not care much for generics.
Related
This question already has answers here:
Efficiently mutate a vector while also iterating over the same vector
(2 answers)
Is there an elegant solution to modifying a structure while iterating?
(1 answer)
How to idiomatically iterate one half of an array and modify the structure of the other?
(1 answer)
How can I iterate a vector once and insert/remove/modify multiple elements along the way?
(1 answer)
How can I modify a collection while also iterating over it?
(2 answers)
Closed 4 years ago.
I have a struct GameLog that holds a Vec<Steps>. Steps holds a Vec<FieldData> and FieldData consists only of basic data types.
I create instances of these types using serde_json. After the deserialisation is done, I need to iterate over all the steps in the GameData and add to it the past version of the fields that are changed in the next turn it doesn't already contain.
I have a working Java implementation I'm trying to port to Rust, but I just can't figure this out, probably because I don't know enough about Rust's insides.
The current code looks like this:
let data = load_data("Path/to/json");
let mut gamelog: Vec<Vec<FieldData>> = Vec::with_capacity(data.steps.len() + 1);
gamelog.push(Vec::with_capacity(data.init.fields.len()));
gamelog[0] = data.init.fields;
for i in 1..(data.steps.len() - 1) {
gamelog.push(Vec::with_capacity(data.steps[i - 1].fields.len()));
gamelog[i] = data.steps[i - 1].fields.clone();
for future_field in &data.steps[i + 1].fields {
let mut inside = false;
for current_field in &data.steps[i].fields {
if current_field.x == future_field.x && current_field.y == future_field.y {
inside = true;
}
}
if !inside {
for j in i..0 {
let mut insideb = false;
for past_field in &data.steps[j].fields {
if future_field.x == past_field.x && future_field.y == past_field.y {
gamelog[i].push(past_field.clone());
insideb = true;
break;
}
}
if insideb {
break;
}
}
}
}
}
However, this only works by creating copies of the vectors and fields and creates a new Vec.
When I try to manipulate the Vec directly, I most often get a "can't move out of borrow" error on the for .. in data.steps[?].fields lines
What would a proper (and possibly much more idiomatic) way of directly manipulating the Vecs in the struct?
I've written the following code for a heap of Node*s, which are found in module node:
import std.exception, std.container;
public import node;
alias NodeArray = Array!(const (Node)*);
alias NodeHeap = BinaryHeap!(NodeArray, cmp_node_ptr);
auto make_heap() {
return new NodeHeap(NodeArray(cast(const(Node)*)[]));
}
void insert(NodeHeap* heap, in Node* u) {
enforce(heap && u);
heap.insert(u);
}
pure bool cmp_node_ptr(in Node* a, in Node* b) {
enforce(a && b);
return (a.val > b.val);
}
I then tried running the following unit tests on it, where make_leaf returns a Node* initialized with the argument given:
unittest {
auto u = make_leaf(10);
auto heap = make_heap();
insert(heap, u); //bad things happen here
assert(heap.front == u);
auto v = make_leaf(20);
insert(heap, v);
assert(heap.front == u); //assures heap property
}
The tests make it to the line I comment-marked, and then throw an enforcement error on the line enforce(a && b) in cmp_node_ptr. I'm totally lost as to why this is happening.
you are doing wrong thing in this operator:
NodeArray(cast(const(Node)*)[])
you obviously want to create empty NodeArray, but what you really got is NodeArray with one null item. NodeArray constructor takes list of values for new array as arguments, and you passing one "empty array" (which is essentially null), thus creating NodeArray with one null element.
the correct way is just:
NodeArray()
i.e.:
auto make_heap() {
return new NodeHeap();
}
make this change and everything will be fine.
p.s. it seems that D notation for multiple arguments of type U (U[] values...) made you think that constructor accepts another array as initialiser.
p.p.s. sorry, fixed make_heap() code: accidentally forgot to write "NodeArray()" in it. and edited it again, as empty NodeArray() call is not necessary there. double fault!
I'm just starting to evaluate Rust. Using Rust and the sqlite3 repo on Github, I'm attempting to determine EOF for a Cursor. I'm not sure how to do that "correctly", I think it may be via the "match" statement.
The 2nd line in the following 2 lines is how I'm currently determining EOF, but this is obviously not the "correct" way:
let oNextResult:sqlite::types::ResultCode = oDbCursor.step();
tDone = (fmt!("%?", oNextResult) == ~"SQLITE_DONE");
The following is the unfinished function containing the above 2 lines. Please excuse the lack of Rust naming-convention, but I will look at implementing that.
/********************
**** Update Data ****
*********************/
fn fUpdateData(oDb1:&sqlite::database::Database, iUpdateMax:int) -> bool {
println(fmt!("Updating %d Rows .......", iUpdateMax));
let sSql:~str = fmt!("Select ikey, sname, iborn, dbal from test LIMIT %d",
iUpdateMax);
let oDbExec = oDb1.exec(sSql);
if oDbExec.is_err() {
println(fmt!("Select Failed! : %?, sql=%s", oDbExec, sSql));
return false;
}
println("Select succeeded. Processing select list .....");
let mut iUpdateCount: int = 0;
let oDbCursor:sqlite::cursor::Cursor = oDb1.prepare(sSql, &None).unwrap();
let mut tDone:bool = false;
while !tDone {
let oNextResult:sqlite::types::ResultCode = oDbCursor.step();
tDone = (fmt!("%?", oNextResult) == ~"SQLITE_DONE");
if !tDone {
let sKey = oDbCursor.get_text(0);
let sName = oDbCursor.get_text(1);
let sBorn = oDbCursor.get_text(2);
let sBal = oDbCursor.get_text(3);
println(fmt!("skey = %s, sname = %s, sBorn = %s, sBal = %s", sKey,
sName, sBorn, sBal));
iUpdateCount += 1;
}
}
println(fmt!("Update succeeded, items updated = %d", iUpdateCount));
return true;
}
I don't know if there is a correct way at the moment but you can also the result codes from the types module:
use sqlite::types::ResultCode;
and then do something like this so there's no need for using fmt!
while cursor.step() == SQLITE_ROW {...}
or this:
while cursor.get_column_count() != 0 {...; cursor.step()}
Function get_column_count returns an int. If there's no data it will return 0. It calls int sqlite3_data_count(sqlite3_stmt *pStmt); under the hood and here's what sqlite docs say about it:
The sqlite3_data_count(P) interface returns the number of columns in
the current row of the result set of prepared statement P. If prepared
statement P does not have results ready to return (via calls to the
sqlite3_column_*() of interfaces) then sqlite3_data_count(P) returns
0. The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. The sqlite3_data_count(P) routine returns 0 if the previous
call to sqlite3_step(P) returned SQLITE_DONE. The
sqlite3_data_count(P) will return non-zero if previous call to
sqlite3_step(P) returned SQLITE_ROW, except in the case of the PRAGMA
incremental_vacuum where it always returns zero since each step of
that multi-step pragma returns 0 columns of data.
As it's mentioned on the readme file rustsqlite interface is not finalized, watch out for changes.
I have to copy certain elements from a std::map into a vector.
It should work like in this loop:
typedef int First;
typedef void* Second;
std::map<First, Second> map;
// fill map
std::vector<Second> mVec;
for (std::map<First, Second>::const_iterator it = map.begin(); it != map.end(); ++it) {
if (it->first % 2 == 0) {
mVec.push_back (it->second);
}
}
Since I'd like to avoid using any functors, but use boost::lambda instead, I tried using std::copy, but can't get it right.
std::copy (map.begin(), map.end(), std::back_inserter(mVec)
bind(&std::map<int, void*>::value_type::first, _1) % 2 == 0);
I'm new to lambda expressions, and I can't figure it out how to use them correctly.
I didn't get any useful results on Google or StackOverflow either.
This question is similar
What you would need in STL would be a transform_if algorithm. Then you would have to write:
transform_if (mymap.begin(), mymap.end(),
back_inserter(myvec),
bind(&std::map<First, Second>::value_type::second, _1) ,
(bind(&std::map<First, Second>::value_type::first, _1) % 2) == 0 );
The code for transform_if is taken from this unrelated question and it is:
template<class InputIterator, class OutputIterator, class UnaryFunction, class Predicate>
OutputIterator transform_if(InputIterator first,
InputIterator last,
OutputIterator result,
UnaryFunction f,
Predicate pred)
{
for (; first != last; ++first)
{
if( pred(*first) )
*result++ = f(*first);
}
return result;
}
I think there is no other way to perform both steps (transform and conditional copy) at once using STL algorithms.
You can use boost range adaptors to achieve that.
using namespace boost::adaptors;
boost::copy( map | filtered( [] (const pair<First,Second> &p)->bool {return p.first % 2 == 0;})
| transformed( [] (const pair<First,Second> &p) {return p.second;}),
std::back_inserter(mVec));
Hey I'm working on a problem where you would print a string vertically using recursion. I know how to do this if i were to use a for loop:
for (int i = 0; i < str.length(); i++) {
System.out.println(str.charAt(i));
but i'm not entirely sure how to do it using recursion. I took care of the base case but i'm not sure how to continue:
if (str == null || str.equals("")) {
return str;
Any help will be greatly appreciated. Thanks!!!
When in doubt, you can always translate iteration directly into recursion:
for (int i = 0; i < str.length(); i++)
System.out.println(str.charAt(i));
...becomes:
public void printVertical(String str, int i) {
if (i < str.length()) {
System.out.println(str.charAt(i));
printVertical(str, i + 1);
}
}
String inputStr = ...
printVertical(inputStr, 0);
Note that there are many ways of doing this that are more elegant. This feels like a homework assignment to me. I would suggest you find one of the subjectively better approaches rather than using my "blind translation" of your loop.
public void printVertString(String str) {
if (str != null && str.length > 0) //1 base condition
{
System.out.println(str.charAt(0)) //2 print first char
printVertString(str.substring(1)) //3 recursive call, but first char is omitted
}
}
What this does:
Check that the string is not empty (the base case). If it is, then there shouldn't be any more recursion and the method just returns without doing anything
Print the first character of the string
Calls itself, but only with the second character onwards
So if you send it a str = "CAT", the following is what happens (indents differentiate the different calls of the same function)
1 str is "CAT" --> not empty
2 print "C"
3 call printVertString "AT"
1 str is "AT" --> not empty
2 print "A"
3 call printVertString "T"
1 str is "T" --> not empty
2 print "T"
3 call printVertString ""
1 str is "" --> EMPTY
return
The key to understanding recursion is understanding recursion. (bah dum bum)
But seriously, you should think about this in terms of making a smaller problem from the problem that you already have. In this example, you have a string of some length; how could you print part of that string and then have a smaller string with which to repeat the process? That's the essential idea of recursion.
Your base case is correct, so one way you could go about it using the Java libraries and your code above:
public String printVertical(String str)
{
if (str == null || str.equals(""))
{
return str;
}
else
{
System.out.println(str.charAt(0));
return printVertical(str.substring(1, str.length);
}
}
Why would you want to do something like this? This is clearly a case where an iterative process would be clearer and easier to implement than a recursive implementation.
There are a few ways to handle this recursively. Since you are working with Java, I would recommend that you look at the String.substring method in the java core library.
This should do the trick:
void foo (final String str) {
if (null != str && str.length > 0) {
System.out.println(str.charAt(0))
foo(str.substring(1))
}
}
The point of recursion is that you have a function that calls itself.