for (int k = 0; k < proc.Count; k++){
for (int i = k + 1; i < proc.Count; i++){
if (proc[k].arrivalTime >= proc[i].arrivalTime && proc[k].priority >= proc[i].priority && proc[k].brust > proc[i].brust){
temp = proc[i];
proc[i] = proc[k];
proc[k] = temp;
}
}
}
Input
Process Arrival Brust Priority
P0 0 10 5
P1 1 3 1
P2 1 2 1
P3 5 1 5
P4 5 8 2
I want to sort these processes following these rules
1) If the process arrived alone it'll work no matter what.
2) If 2 processes arrived in the same time, we gonna check the priority if the first one has higher priority(lower number) it'll work first, and if they have the same priority we gonna let the one who has lower Brust work first.
There's problem with last 2 processes where's the problem?
P3 5 1 5
P4 5 8 2
process 4 should work because it has higher priority
Rather than bubble sorting (which is the one of the least efficient ways to sort collections), why not just sort the collection using LINQ's OrderBy(), e.g.
var sorted = proc.OrderBy(x => x.arrivalTime)
.ThenBy(x => x.priority)
.ThenBy(x => x.brust)
.ToList(); // or .ToArray() or whatever collection you need
You provided very clear explanation of the rules.
Now check this line
if (proc[k].arrivalTime >= proc[i].arrivalTime && proc[k].priority >= proc[i].priority && proc[k].brust > proc[i].brust)
Is it doing what the rules say? Definitely no. The direct translation of the rules would be something like this
if (proc[k].arrivalTime > proc[i].arrivalTime ||
(proc[k].arrivalTime == proc[i].arrivalTime &&
(proc[k].priority > proc[i].priority ||
(proc[k].priority == proc[i].priority && proc[k].brust > proc[i].brust))))
Better and more readable would be
int compare = proc[k].arrivalTime.CompareTo(proc[i].arrivalTime);
if (compare == 0)
compare = proc[k].priority.CompareTo(proc[i].priority);
if (compare == 0)
compare = proc[k].brust.CompareTo(proc[i].brust);
if (compare > 0)
{
// ...
}
which is the standard way of doing multi key comparison.
Mahmoud, your if-statment is incorrect because it will evaluate to true if ALL conditions are met, your statement should cascade the conditions.
for (int k = 0; k < proc.Count; k++){
for (int i = k + 1; i < proc.Count; i++){
bool doSwap = false;
if (proc[k].arrivalTime > proc[i].arrivalTime)
{
doSwap = true;
}
else if (proc[k].arrivalTime == proc[i].arrivalTime)
{
if(proc[k].priority > proc[i].priority)
{
doSwap = true;
}
else if (proc[k].priority == proc[i].priority )
{
if(proc[k].brust > proc[i].brust)
{
doSwap = true;
}
}
}
if(doSwap)
{
temp = proc[i];
proc[i] = proc[k];
proc[k] = temp;
}
}
}
Related
Here is my code, for my if statements I want to have it between two values for example:
if(rating < 5 > 2);
So I'm saying i want it to only print the command if that value is below 5 but higher than 2.
Is there a way to do this? Thank you for your time.
Here is my code.
public static void Main(string[] args)
{
Console.WriteLine("What would you rate starcraft out of 10?");
int rating = Console.Read();
if (rating < 5) ;
{
Console.WriteLine("Not good enough!");
Console.ReadLine();
}
if (rating > 5) ;
{
Console.WriteLine("OOOOOOOOO yeeeeeeee");
Console.ReadLine();
}
if (rating > 8) ;
{
Console.WriteLine("We are bestfriends now ;)");
Console.ReadLine();
Use conditional logical AND operator &&:
if (rating < 5 && rating > 2)
{
}
Or pattern matching (read more #1, read more #2):
if (rating is < 5 and > 2)
{
}
P.S.
You can refactor a bit with switch expression and ordering the checks to remove some code repetition and improve readability (note that original code does not cover rating == 5 case compared to the following):
var rating = ...;
var message = rating switch
{
< 2 => "Terrible",
< 5 => "Not good enough!",
< 8 => "OOOOOOOOO yeeeeeeee",
_ => "We are bestfriends now ;)"
};
Console.WriteLine(message);
Console.ReadLine();
To avoid complications, you can sort ratings' thresholds and then check them in order with a help of if ... else if pattern, e.g. having
2 - Nightmare
5 - Not good enough!
8 - OOOOOOOOO yeeeeeeee
more - We are bestfriends now
We can put it as
if (rating <= 2) // 2 or less
Console.WriteLine("Nightmare");
else if (rating <= 5) // (2..5]
Console.WriteLine("Not good enough!");
else if (rating <= 8) // (5..8]
Console.WriteLine("OOOOOOOOO yeeeeeeee");
else // more than 8
Console.WriteLine("We are bestfriends now");
Console.ReadLine();
I'm working on a dictionary table and required to find out all possible combination of characters in a word. Thanks to https://codereview.stackexchange.com/questions/28248/implement-a-function-that-prints-all-possible-combinations-of-the-characters-in , I got below working so far:
public List<string> findAllOccurance(string str)
{
var results = from e in Range(0, BigInteger.Pow(2, str.Length))
let p =
from b in Enumerable.Range(1, str.Length)
select (e & BigInteger.Pow(2, b - 1)) == 0 ? (char?)null : str[b - 1]
select string.Join(string.Empty, p);
return results.ToList();
}
public IEnumerable<BigInteger> Range(BigInteger start, BigInteger count)
{
while (count-- > 0)
{
yield return start++;
}
}
Passing "abc" to above function would returns:
a
b
ab
c
ac
bc
abc
The problem is I actually would like to find out only the "connected" permutations in "original order", for example "abc" should return only
a
b
c
ab
bc
abc
Does anyone have any idea what should I change to achieve above?
By "connected" permutations - you are effectively looking for all substrings from length 1 up to the full length of the string. This can be very easily done with two for loops. The duplicates can be removed by using Linq's Distinct() method.
public List<string> findAllOccurance(string str)
{
List<string> result = new List<string>();
for (int i = 1; i <= str.Length; i++)
{
for (int j=0; j <= str.Length-i; j++)
result.Add(str.Substring(j,i));
}
return result.Distinct().ToList();
}
NOTE - if you really do want to return an empty string - you can either modify the outer loop to start from 0 or simply manually add it after creating the list instance. Modifying the loop will result in str.Length empty strings being added & more work for Distinct() when you know you will only ever always want 1 empty string returned.
List<string> result = new List<string>();
result.Add(String.Empty);
for (int i = 1; i <= str.Length; i++)
.....
I don't know if I understand "connected" right... Maybe you could simply check if a potential result is a part of the original string... Something like this:
public List<string> findAllOccurance(string str)
{
var results = from e in Range(0, BigInteger.Pow(2, str.Length))
let p =
from b in Enumerable.Range(1, str.Length)
select (e & BigInteger.Pow(2, b - 1)) == 0 ? (char?)null : str[b - 1]
let p2 = string.Join(string.Empty, p)
where str.Contains(p2)
select p2;
return results.ToList();
}
public IEnumerable<BigInteger> Range(BigInteger start, BigInteger count)
{
while (count-- > 0)
{
yield return start++;
}
}
For your code, you are performing bitwise operation in order to find all possible subsets. For the case abc your string length is 3. So possible subsets = 2 ^ 3 = 8. Writing them down and matching the rightmost bit with the leftmost index:
Possible cases:
0 0 0 // gives nothing
0 0 1 // gives 'a' (valid)
0 1 0 // gives 'b' (valid)
0 1 1 // gives 'ab' (valid)
1 0 0 // gives 'c' (valid)
1 0 1 // gives 'ac' (invalid as there is a 0 inbetween and not connected)
1 1 0 // gives 'bc' (valid)
1 1 1 // gives 'abc' (valid)
The above is what I understand for what you count as connected. You can easily perform a check to do this with two loops:
int max_size = BigInteger.Pow(2, str.Length);
int str_size = str.Length;
for(int i = 0; i < max_size; ++i)
{
string ans = "";
for(j = 0; j < str_size; ++j)
{
// We check if the jth bit is set, we print the jth element from the string.
if(i & (1 << j))
ans += str[j];
}
else {
if(ans.Length > 0){
// this means we have already added a character and then the next consecutive bit is '0'
ans = "";
break;
}
}
if(ans != ""){
Console.Writeline(ans); // we print the set. you can control this anyway you want.
}
}
}
I have a class RekenReeks which returns numbers starting from 2, multiplied by 2. So {2,4,8,16,32,64}
Now I learned about the TakeWhile and SkipWhile methods as well as LINQ.
So I have created 3 variables which should store exactly the same but my Console.WriteLine only prints selection1 and not 2 and 3.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
RekenReeks reeks = new RekenReeks(2, n => n * 2);
var selection = from i in reeks
where i > 10
&& i < 1000
select i;
var selection2 = reeks.TakeWhile(n => n < 1000 && n > 10);
var selection3 = reeks.SkipWhile(n => n > 1000 && n < 10);
foreach (int i in selection)
{
Console.WriteLine("selection1 {0}",i);
}
foreach (int i in selection2)
{
Console.WriteLine("selection2 {0}", i);
}
foreach (int i in selection3)
{
Console.WriteLine("selection3 {0}", i);
}
Console.ReadLine();
}
}
public class RekenReeks : IEnumerable<int>
{
Func<int, int> getNew;
int number;
public RekenReeks(int starton, Func<int, int> getNewThing)
{
getNew = getNewThing;
number = starton;
}
public IEnumerator<int> GetEnumerator()
{
yield return number;
for (; ; )
{
yield return getNew(number);
number = getNew(number);
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}
Your sequence is unlimited (theoretically). You assume too much. The functionality of your program cannot possibly know that your sequence is strictly monotonic increasing.
var selection = from i in reeks
where i > 10
&& i < 1000
select i;
This will never stop. Because the where will always pull the next value, it does not know it's condition will be satisfied, it always has to check the next value.
var selection2 = reeks.TakeWhile(n => n < 1000 && n > 10);
This will take values, while they are between 11 and 999. As your sequence starts with 2, it will stop right on the first value.
var selection3 = reeks.SkipWhile(n => n > 1000 && n < 10);
This will skip values while they are between 11 and 999. As the first is 2, it will skip none and therefore yield all.
Both TakeWhile() and SkipWhile() start from very beginning of the sequence and stop taking/skipping when condition doesn't meet.
// I've redesigned your ReekenReeks
// [2, 4, 8, 16, 32, 64, ..., 2**30]
var reeks = Enumerable
.Range(1, 30)
.Select(index => 1 << index);
For instance, if you put
var selection2 = reeks
.TakeWhile(n => n < 1000 && n > 10);
since the 1st item of the reeks is 2 the condition n < 1000 && n > 10 doesn't meet TakeWhile stops and returns an empty sequence. The right implemenation is
var selection2 = reeks
.SkipWhile(n => n <= 10)
.TakeWhile(n => n < 1000);
If you want to cut off values from the middle of the sequence (selection3) you have to use Where:
var selection3 = reeks
.Where(n => !(n > 1000 && n < 10)); // cut theses items off
Be careful when printing out an infinine sequence, .Take() is a good choice here:
var selection3 = reeks
.Where(n => n > 1000 && n < 10)
.Take(100); // First 100 items in case the sequence is too long
var selection = from i in reeks
where i > 10
&& i < 1000
select i;
There's no reason for this to ever end. When i is 1024 it won't be yielded, but it will still check then if 2048 is less than 1000, or 4096 is less than 1000, or 8192 is less than 1000 and so on forever (eventually either overflow exception happens or n wraps around to 0 which then keeps being set to 0 * 2 which is still 0).
reeks.TakeWhile(n => n < 1000 && n > 10)
The first value tried is 2. This does not satisfy the predicate n < 1000 && n > 10 because it is not true that 2 > 10. Therefore the taking stops.
reeks.SkipWhile(n => n > 1000 && n < 10)
There is no value of n for which n > 1000 && n < 10. Therefore this is the same as having no SkipWhile at all.
It seems like what you want is:
reeks.SkipWhile(n => n >= 1000 || n <= 10).TakeWhile(n => n < 1000 && n > 10)
Which skips until the first number that meets the criteria is found, then takes all that meet it until the first that does not.
I have some Lists which store values. Now I want to create If-Statements to handle this but that's to much. For example:
if(list1.Count==0 && list2.Count==0)
{
//do something
}
if(list1.Count==0 && list3.Count==0)
{
//do something
}
if(list1.Count==0 && list2.Count==0 && list3.Count==0)
{
//do something
}
so there is a huge amount of if-statements if I have about 10 Lists. Is there a better way to handle that? I haven't found anything useful.
Thanks!
One of the way that i can give the suggestion seeing the code pasted here is that you have some duplicated stuff like this
if(list1.Count==0 && list2.Count==0)
and then
if(list1.Count==0 && list2.Count==0 && list3.Count==0)
One of the suggestion will be to per-calculate the condition like this
bool onetwo = list1.Count==0 && list2.Count==0;
bool thirdalone = list3.Count == 0;
Now the code can be more better like this
if(onetwo){
}
if(onetwo && thirdalone){
}
If you wish you can use the Bitmasking to generate all of them for example , here n is total lists we have.
bool[] statu = new bool[1 << n];
for(int i = 1 ; i < (1<< n) ; i++){
bool result = true;
for(int j = 0 ; j < 32 ; j++){
if(i & ( 1 << j) > 0){
//this position is part of set
if(list[j].count == 0)
result = false;
}
}
status[i] = result;
}
But it is just more semantic way , nothing can be performance enhancement etc..
If you need to check every permutation you can do something like this:
bool b1 = ( list1.count == 0 );
bool b2 = ( list2.count == 0 );
bool b3 = ( list3.count == 0 );
bool b4 = ( list4.count == 0 );
// etc etc
BitArray arr = new BitArray(new bool[4] { b1, b2, b3, b4 });
byte[] bits = new byte[4];
arr.CopyTo(bits, 0);
int x = BitConverter.ToInt32(bits, 0);
switch (x)
{
case 1: // only list 1 is empty
case 2: // only list 2 is empty
case 3: // only list 1 and list 2 are empty
case x: // and so on.
}
I wouldn't say is it's any more readable, but I'd rather maintain something like this is future than a giant if/else/else if block.
I am trying to improve a list collection that i have to replace values that are divisible by two and 10 and replace everything that is divisible by two with dTwo and ten with dTen?
My code works with one divisible statment but not two.
var num = new List<string>();
for (int n = 0; n < 101; n++)
{
num.Add(n % 2 == 0 ? "dTwo" : n.ToString());
num.Add(n % 10 == 0 ? "dTen" : n.ToString());
}
Since any number that is divisible by 10 is also divisible by 2 you have to switch your addition statements, and continue with the next number if you have a number divisible by 10:
var num = new List<string>();
for (int n = 0; n < 101; n++)
{
if( n % 10 == 0)
{
num.Add("dTen");
}
else num.Add(n % 2 == 0 ? "dTwo" : n.ToString());
}
If I can I try avoid using loop controls out side of the defined construct of the actual loop, ie. I prefer to avoid using continue if I can, it sort of feels like using goto statements. For this case, I would go for the plain and simple approach which I believe is readable, maintainable and simple albeit a little more verbose.
You can switch the order of the if/else if statements to change the priority if required, in this case the n % 10 has priority
var num = new List<string>();
for (int n = 0; n < 101; ++n)
{
if (n % 10 == 0)
{
num.Add("dTen");
}
else if (n % 2 == 0)
{
num.Add("dTwo");
}
else
{
num.Add(n.ToString());
}
}
There are two approaches I would take here, the first is verbose, but conveys what you're trying to do in a very readable manner:
var num = new List<string>(101);
for (int i = 0; i < 101 ; i++)
{
if (i == 0)
{
num.Add(i.ToString());
}
else if (i % 10 == 0)
{
num.Add("dTen");
}
else if (i % 2 == 0)
{
num.Add("dTwo");
}
else
{
num.Add(i.ToString());
}
}
The second uses a more concise LINQ-y type approach, like this.
var num = Enumerable.Range(0, 101)
.Select(
n => n == 0 ? n.ToString() :
n % 10 == 0 ? "dTen" :
n % 2 == 0 ? "dTwo" :
n.ToString())
.ToList();
Note that I've also taken into account the 0 edge case, where 0 would otherwise get reported as being divisible by 10.
Which one you go for is largely up to your taste. Personally I'd go for the latter implementation, as it's concise but still conveys the intent of the code. Some very rudimentary tests I've just done shows that it'll execute faster as well.