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.
Related
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.
I want to extract the payload of a HTTP request as a Vec<u8>. In the request, the payload is separated from the rest by the sequence \r\n\r\n, that's why I want to split my Vec at this position, and take the second element.
My current solution is to use the following function I wrote.
fn find_payload_index(buffer: &Vec<u8>) -> usize {
for (pos, e) in buffer.iter().enumerate() {
if pos < 3 {
continue
}
if buffer[pos - 3] == 13 && buffer[pos - 2] == 10 && buffer[pos - 1] == 13 && buffer[pos] == 10 {
return pos + 1;
}
}
0
}
13 is the ASCII value of \r and 10 the value of \n. I then split by the returned index. While this solution is technically working, it feels very unclean, and I was wondering how to do this in a more elegant way.
First of:
A function should almost never have a &Vec<_> parameter.
See Why is it discouraged to accept a reference to a String (&String), Vec (&Vec), or Box (&Box) as a function argument?.
Don't use the magic values 10 and 13, Rust supports byte literals: b'\r' and b'\n'.
As for your question: I believe you can make it a bit simpler using windows and matches! with a byte string literal pattern:
fn find_payload_index(buffer: &[u8]) -> Option<usize> {
buffer
.windows(4)
.enumerate()
.find(|(_, w)| matches!(*w, b"\r\n\r\n"))
.map(|(i, _)| i)
}
Permalink to the playground with test cases.
Note that slice has a starts_with method which will more easily do what you want:
fn find_payload_index(buffer: &[u8]) -> usize {
for i in 0..buffer.len() {
if buffer[i..].starts_with(b"\r\n\r\n") {
return i
}
}
panic!("malformed buffer without the sequence")
}
I see no reason to use enumerate if the actual element itself never be used, simply looping over 0..buffer.len() seems the easiest solution to me.
I have also elected to make the function panic, rather than return 0, when the sequence be malformed, which I believe is more proper, though you should probably in the end return some kind of Result value, and handle the error case cleanly, if the input be malformed, but you should never return 0 in this case.
A shorter alternative for #mccarton answer would be to use position:
fn find_payload_index(buffer: &[u8]) -> Option<usize> {
buffer
.windows(4)
.position(|arr| arr == b"\r\n\r\n")
}
I have a func. that takes in two variables as string pointers, these parameters need to be passed to another func. but I need to convert the them to strings, with empty string "" if it's a nil pointer, I have achieved this, but find my version cumbersome. How can it be simplified / prettified ?
func allMetricVolumes(start, end *string, measuredType []string, volumeUUID string) []*models.ResourceMetrics {
var startStr = ""
if start != nil {
startStr = *start
}
var endStr = ""
if end != nil {
endStr = *end
}
return database.AllDataPointsMetricVolumes(startStr, endStr, measuredType, volumeUUID)
}
EDIT:
This is also an option that I came up with, just to create a helper func. but the main argument still stands though, that if it can be shorter?
func stringPointerToString(input *string) string {
if input != nil {
return *input
}
return ""
}
The way you wrote it is the shortest way.
The question though why the func requires strings as pointers?
It seems that you're trying to solve the problem with optional parameters. database.AllDataPointsMetricVolumes function already allows an empty string. So, if you pass value instead of pointers, you can obsolete the function and use the database.AllDataPointsMetricVolumes directly.
I have n integers and I need a quick logic test to see that they are all different, and I don't want to compare every combination to find a match...any ideas on a nice and elegant approach?
I don't care what programming language your idea is in, I can convert!
Use a set data structure if your language supports it, you might also look at keeping a hash table of seen elements.
In python you might try
seen={}
n_already_seen=n in seen
seen[n]=n
n_already_seen will be a boolean indicating if n has already been seen.
You don't have to check every combination thanks to commutivity and transitivity; you can simply go down the list and check each entry against each entry that comes after it. For example:
bool areElementsUnique( int[] arr ) {
for( int i=0; i<arr.Length-1; i++ ) {
for( int j=i+1; j<arr.Length; j++ ) {
if( arr[i] == arr[j] ) return false;
}
}
return true;
}
Note that the inner loop doesn't start from the beginning, but from the next element (i+1).
You can use a Hash Table or a Set type of data structure that using hashing. Then you can insert all of the elements into the hashtable or hashset, and either as you insert, check if the element is already in the table/set. If for some reason you don't want to check as you go, you can just insert all the numbers and then check to see if the size of the structure is less than n. If it is less than n, there had to be repeated elements. Otherwise, they were all unique.
Here is a really compact Java solution. The time-complexity is amortized O(n) and the space complexity is also O(n).
public boolean areAllElementsUnique(int [] list)
{
Set<Integer> set = new HashSet<Integer>();
for (int number: list)
if (set.contains(number))
return false;
else
set.add(number);
return true;
}
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));