Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 08, 2015 Dynamic array and foreach loop | ||||
---|---|---|---|---|
| ||||
I'm writing a program that rotates numbers then asks the user if a new set of numbers should be rotated. I'm having trouble using a Foreach loop to fill a dynamic array with the elements to be rotated. Here's my code, I add a TAB when a loop is inside a loop and and do that too to the statements inside and to IF's also. import std.stdio; /*Input : Quantity of elements, elements y positions to be rotated*/ /*Output : Elements rotated as requested*/ void main() { int liEle, liCount, liRot, liAcc; int[] liaOrig, liaFinal; immutable kArr=50; /*Variables : Quantity of elements to be used, Counter variable for loops, Array for original sequence, Array for final sequence, Variable for positions to rotate and Action counter variable. */ char lcRot;//Variable for options do {//Complete program. Also runs when an other sequence is to be used do {//Validation loop for the array. Must be positive write ("How many elements need to be used? "); readf(" %d", &liEle); if(liEle<2) write("Must be a number greater than 1\n"); }while(liEle<2 || liEle>kArr); liaOrig.length = liEle; liaFinal.length = liEle; foreach(num; liaOrig[0..$]) {//Data input loop write("Input the element : ", num+1, " "); readf(" %d", &liaOrig[num]); } do { do { write("How many positions do you wish to rotate ? "); readf(" %d", &liRot); if(liRot<1) write("Input a positive number\n"); }while(liRot<1);//Keep asking if a negatice number liRot%=liEle;// Reduce rotations for minimal executino for(liCount=liEle-1, liAcc=liRot-1; liAcc>=0; liCount--, liAcc--) {//Revrse loop for rotation liaFinal[liAcc]=liaOrig[liCount]; } for(liCount=0; liRot<liEle; liCount++, liRot++) {//Complementary loop for missed elements liaFinal[liRot]=liaOrig[liCount]; } write("The original patter is : ");//Output the original sequence for(liCount=0; liCount<liEle; liCount++) { write(liaOrig[liCount], " "); } write("\n");//New line for next loop output write("The final is : ");//Final sequence output for(liCount=0; liCount<liEle; liCount++) {//loop for Final sequence output write(liaFinal[liCount], " "); } write("\nDo you want to rotate again ? y/n ");//Option to rotate again readf(" %c", &lcRot); if(lcRot == 'y' || lcRot == 'Y') { for(liCount=0; liCount<liEle; liCount++)//Keep the Final sequence liaOrig[liCount]=liaFinal[liCount]; } else { write("Do you want to make an adicional sequence ? a/A ");//Option to make a new sequence readf(" %c", &lcRot); } }while(lcRot == 'y' || lcRot == 'Y'); }while(lcRot == 'A' || lcRot == 'a');//Loop for restarting the program write("End of program\n");//Nothing else to do } |
August 08, 2015 Re: Dynamic array and foreach loop | ||||
---|---|---|---|---|
| ||||
Posted in reply to Binarydepth | Here's what happens : How many elements need to be used? 5 Input the element : 1 1 Input the element : 1 2 Input the element : 1 3 Input the element : 1 4 Input the element : 1 5 How many positions do you wish to rotate ? 3 The original patter is : 5 0 0 0 0 The final is : 0 0 0 5 0 Do you want to rotate again ? y/n y How many positions do you wish to rotate ? 2 The original patter is : 0 0 0 5 0 The final is : 5 0 0 0 0 Do you want to rotate again ? y/n n Do you want to make an adicional sequence ? a/A a How many elements need to be used? 4 Input the element : 1 1 Input the element : 1 2 Input the element : 1 3 core.exception.RangeError@gen014.d(31): Range violation ---------------- 0x4077ef _Dmain ???:0 0x41684e void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll().void __lambda1() ../../../../src/libphobos/libdruntime/rt/dmain2.d:408 0x416abe void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) ../../../../src/libphobos/libdruntime/rt/dmain2.d:383 0x416d18 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() ../../../../src/libphobos/libdruntime/rt/dmain2.d:408 0x416abe void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) ../../../../src/libphobos/libdruntime/rt/dmain2.d:383 0x416c45 _d_run_main ../../../../src/libphobos/libdruntime/rt/dmain2.d:416 0x7f8c84eeda3f __libc_start_main ???:0 0x406058 _start ???:0 0xffffffffffffffff ??? ???:0 |
August 08, 2015 Re: Dynamic array and foreach loop | ||||
---|---|---|---|---|
| ||||
Posted in reply to Binarydepth | On Saturday, 8 August 2015 at 15:57:15 UTC, Binarydepth wrote:
> Here's what happens :
>
> How many elements need to be used? 5
> Input the element : 1 1
> Input the element : 1 2
> Input the element : 1 3
> Input the element : 1 4
> Input the element : 1 5
> How many positions do you wish to rotate ? 3
> The original patter is : 5 0 0 0 0
> The final is : 0 0 0 5 0
> Do you want to rotate again ? y/n y
> How many positions do you wish to rotate ? 2
> The original patter is : 0 0 0 5 0
> The final is : 5 0 0 0 0
> Do you want to rotate again ? y/n n
> Do you want to make an adicional sequence ? a/A a
> How many elements need to be used? 4
> Input the element : 1 1
> Input the element : 1 2
> Input the element : 1 3
> core.exception.RangeError@gen014.d(31): Range violation
> ----------------
> 0x4077ef _Dmain
> ???:0
> 0x41684e void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll().void __lambda1()
> ../../../../src/libphobos/libdruntime/rt/dmain2.d:408
> 0x416abe void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate())
> ../../../../src/libphobos/libdruntime/rt/dmain2.d:383
> 0x416d18 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll()
> ../../../../src/libphobos/libdruntime/rt/dmain2.d:408
> 0x416abe void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate())
> ../../../../src/libphobos/libdruntime/rt/dmain2.d:383
> 0x416c45 _d_run_main
> ../../../../src/libphobos/libdruntime/rt/dmain2.d:416
> 0x7f8c84eeda3f __libc_start_main
> ???:0
> 0x406058 _start
> ???:0
> 0xffffffffffffffff ???
> ???:0
This is happening because 'num' is reading the value of each element in the array; it's not a count. Once it reads the 5 in element, it attempts to put the next number into element 5, which of course doesn't exist.
This is also why the first time through there is only one value in the array that isn't 0: 'num' the first time through is always zero because the values of the dynamic array are .init-ed to zero.
You can fix it like the following:
foreach(num, element; liaOrig) {//Data input loop
writefln("num: %s current element: %s liaOrig.length: %s", num, element, liaOrig.length);
write("Input the element : ", num+1, " ");
readf(" %d", &liaOrig[num]);
}
Now 'num' is just an iterative number starting from 0 (the .init value of an int), while the actual element value is stored in 'element'. I added the writefln() statement to make it a bit more clear during runtime.
As an addenum, you don't need the liaOrig[0 .. $] in the foreach statement; just the name of the array variable is required to walk the entire array.
Hope this helps!
|
August 08, 2015 Re: Dynamic array and foreach loop | ||||
---|---|---|---|---|
| ||||
Posted in reply to DarthCthulhu | On Saturday, 8 August 2015 at 17:19:08 UTC, DarthCthulhu wrote:
> You can fix it like the following:
>
> foreach(num, element; liaOrig) {//Data input loop
>
> writefln("num: %s current element: %s liaOrig.length: %s", num, element, liaOrig.length);
>
> write("Input the element : ", num+1, " ");
> readf(" %d", &liaOrig[num]);
> }
>
> Now 'num' is just an iterative number starting from 0 (the .init value of an int), while the actual element value is stored in 'element'. I added the writefln() statement to make it a bit more clear during runtime.
>
> As an addenum, you don't need the liaOrig[0 .. $] in the foreach statement; just the name of the array variable is required to walk the entire array.
>
> Hope this helps!
Thanks that fixed it. I just realized that I'm doing it wrong. This is the new code :
foreach(num; 0..liEle) {//Data input loop
write("Input the element : ", num+1, " ");
readf(" %d", &liaOrig[num]);
}
|
August 08, 2015 Re: Dynamic array and foreach loop | ||||
---|---|---|---|---|
| ||||
Posted in reply to Binarydepth | On Saturday, 8 August 2015 at 18:24:48 UTC, Binarydepth wrote: > On Saturday, 8 August 2015 at 17:19:08 UTC, DarthCthulhu wrote: >> Now 'num' is just an iterative number starting from 0 (the .init value of an int), while the actual element value is stored in 'element'. I added the writefln() statement to make it a bit more clear during runtime. >> >> As an addenum, you don't need the liaOrig[0 .. $] in the foreach statement; just the name of the array variable is required to walk the entire array. >> >> Hope this helps! > > Thanks that fixed it. I just realized that I'm doing it wrong. This is the new code : > > foreach(num; 0..liEle) {//Data input loop > > write("Input the element : ", num+1, " "); > readf(" %d", &liaOrig[num]); > } Even better : foreach(num; 0..liaOrig.length |
August 09, 2015 Re: Dynamic array and foreach loop | ||||
---|---|---|---|---|
| ||||
Posted in reply to Binarydepth | On Saturday, 8 August 2015 at 18:28:25 UTC, Binarydepth wrote:
>> This is the new code :
>>
>> foreach(num; 0..liEle) {//Data input loop
>>
>> write("Input the element : ", num+1, " ");
>> readf(" %d", &liaOrig[num]);
>> }
>
> Even better :
>
> foreach(num; 0..liaOrig.length
I believe they usually do something like:
foreach( num, ref elem; liaOrig){
}
which creates the index num and the reference to the element of range liaOrig.
It also seems that a lot of discussion is going on about reducing use of foreach loops in their preferred style, so you might want to try some of that.
|
August 09, 2015 Re: Dynamic array and foreach loop | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jay Norwood | On Sunday, 9 August 2015 at 00:22:53 UTC, Jay Norwood wrote:
> On Saturday, 8 August 2015 at 18:28:25 UTC, Binarydepth wrote:
>>> This is the new code :
>>>
>>> foreach(num; 0..liEle) {//Data input loop
>>>
>>> write("Input the element : ", num+1, " ");
>>> readf(" %d", &liaOrig[num]);
>>> }
>>
>> Even better :
>>
>> foreach(num; 0..liaOrig.length
>
> I believe they usually do something like:
>
> foreach( num, ref elem; liaOrig){
>
> }
>
> which creates the index num and the reference to the element of range liaOrig.
>
> It also seems that a lot of discussion is going on about reducing use of foreach loops in their preferred style, so you might want to try some of that.
So I should use the REF like this ?
import std.stdio : writeln;
void main() {
immutable a=5;
int[a] Arr;
foreach(num; 0..a) {
Arr[num] = num;
}
foreach(num, ref ele; Arr) {
writeln(Arr[ele]+1);//Using the REF
}
}
|
August 09, 2015 Re: Dynamic array and foreach loop | ||||
---|---|---|---|---|
| ||||
Posted in reply to Binarydepth | On Sunday, 9 August 2015 at 15:37:23 UTC, Binarydepth wrote:
>
> So I should use the REF like this ?
>
> import std.stdio : writeln;
> void main() {
> immutable a=5;
> int[a] Arr;
> foreach(num; 0..a) {
> Arr[num] = num;
> }
> foreach(num, ref ele; Arr) {
> writeln(Arr[ele]+1);//Using the REF
> }
> }
No. `ele` is the array element; reindexing the array with it is incorrect. `ref` just means that you can assign back to the array (like `ele = 123; assert(Arr[num] == 123);`); it's unnecessary here though.
|
August 09, 2015 Re: Dynamic array and foreach loop | ||||
---|---|---|---|---|
| ||||
Posted in reply to Binarydepth | On Sunday, 9 August 2015 at 15:37:23 UTC, Binarydepth wrote:
> So I should use the REF like this ?
>
> import std.stdio : writeln;
> void main() {
> immutable a=5;
> int[a] Arr;
> foreach(num; 0..a) {
> Arr[num] = num;
> }
> foreach(num, ref ele; Arr) {
> writeln(Arr[ele]+1);//Using the REF
> }
> }
The reference v is to the array member in this case, rather than making a copy. In the last loop c is a copy. No big deal for this case of int Arr members, but if Arr was made up of struct members, you might not want to be making copies.
The i+3 initialization is just so you can see that v is the Arr member (not the index) in the other loops.
import std.stdio : writeln;
void main() {
immutable a=5;
int[a] Arr;
foreach(i, ref v; Arr) {
v = i+3;
}
foreach( ref v; Arr) {
writeln(v);
}
foreach( c; Arr) {
writeln(c);
}
}
|
August 09, 2015 Re: Dynamic array and foreach loop | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jay Norwood | On Sunday, 9 August 2015 at 16:42:16 UTC, Jay Norwood wrote:
> The i+3 initialization is just so you can see that v is the Arr member (not the index) in the other loops.
>
> import std.stdio : writeln;
> void main() {
> immutable a=5;
> int[a] Arr;
> foreach(i, ref v; Arr) {
> v = i+3;
> }
> foreach( ref v; Arr) {
> writeln(v);
> }
> foreach( c; Arr) {
> writeln(c);
> }
> }
Oooh... I like how this works
import std.stdio : writeln, readf;
void main() {
immutable a=5;
int[a] Arr;
int nim;
foreach(num, ref nem; Arr) {
readf(" %s", &nem);
}
foreach(num; Arr) {
writeln(num);
}
}
|
Copyright © 1999-2021 by the D Language Foundation