I want to create a backtrack that select's me the best value of tasks in my generic list.
This is how my generic list looks.
I have a method that sorts my list by the price. I have 3 type of "task" Urgent,Return and Normal.
I fill my list up that my Urgent tasks as first (sorted by the price) then return tasks and then normal. And i want the highest value of price in 8 hours but I need to finish urgent first and then return tasks if I still have time and last the normal tasks.
class GenerikusLancoltLista<T> : IEnumerable
{
class ListaElem
{
public T data;
public ListElement next;
}
ListaElem Head;
public GenerikusLancoltLista()
{
Head = null;
}
public void PrioritasiSorBeszuras(T paste)
{
ListElement new = new ListElement();
uj.data = paste;
if (Head == null)
{ Head = new; }
else
{
if ((Head.data as IComparable).CompareTo(paste) >= 0)
{
new.next = Head;
Head = new;
}
else
{
ListElement p = Head;
ListElement e = null;
while (p != null && (p.data as IComparable).CompareTo(paste) < 0)
{
e = p;
p = p.next;
}
if (p == null)
{ e.next = new; }
else
{
new.next = p;
e.next = new;
}
}
}
}
My base task looks like this
interface ITask:IComparable
{
string Name { get; }
int price { get; }
int hour { get; }
int Priority { get; }
}
So I know bactrack should look something like this.
But I dont know how to figure it out a solution that works.
abstract class BacktrackBase
{
int N;
GenerikusLancoltLista<ITask> R;
int[] M;
public BacktrackBase(int n, GenerikusLancoltLista<ITask> r, int[] m)
{
N = n;
R = r;
M = m;
}
protected abstract bool Ft(int level, ITask task);
protected abstract bool Fk(int level, ITask task, ITask[] E);
void Backtrack(int level,Task[] E, ref bool have)
{
int i = -1;
while (!have && i <M[level] - 1)
{
i++;
if (Ft(level, R[level, i]))
{
if (Fk(level, R[level, i], E))
{
E[level] = R[level, i];
if (level == N - 1)
{
have = true;
}
else
{
Backtrack(level + 1, E, ref have);
}
}
}
}
}
I want to fill my 8 hours with works with the best value
for example a work looks like this: Dog walking,10000,3
so "name","price","time"
Each work has a type, "urgent","return","normal".
I need to fit urgent works first with in my 8 hours with the best value.
Related
I have a class Form1 and a class MyList. I want to create a program that puts character into List and has a pointer that shows on next one.
My problem is that everytime when I call class MyList, the pointer resets.
How can I solve the problem.
It is a school project an it must be done on this way, with pointers.
Thanks for all answers!
namespace Data {
public partial class Form1 : Form
{
char character = "a"
int index = 0;
MyList a = new MyList();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) //On click get new index and character and put in a List.
{
a.PutIn(index, character);
}
}
}
MyList class:
namespace Data
{
public unsafe struct list
{
public char x;
public list* next;
}
public unsafe partial class MyList
{
list* first = null;
list* last = null;
int index;
public unsafe MyList() { Initialize(); }
public unsafe void Initialize()
{
first = null;
last = null;
index = -1;
}
~MyList()
{
do{
Emty(0);
}while (!IsEmpty());
}
public unsafe void PutIn(int place, char character)
{
if (((index+1)<place)||(place<0))
MessageBox.Show("Index is too high!");
else
{
if (IsEmpty())
{
list temp = new list();
list* temp_pointer = &temp;
temp_pointer->next = null;
temp_pointer->x = character;
first = temp_pointer;
last = temp_pointer;
temp_pointer = null;
index++;
}
else if (place == (index + 1))
{
list temp = new list();
list* temp_pointer = &temp;
temp_pointer->next = null;
temp_pointer->x = character;
last->next = temp_pointer;
last = temp_pointer;
temp_pointer = null;
index++;
}
}
}
}
The problem is that you are allocating list as a local and it is not guaranteed to last any longer than the scope in which it is defined (in fact, the guarantee only makes sense for managed code anyway - the runtime compiler can get rid of it long before the scope ends if it wants to).
You really want to allocate the object somewhere where it will last a bit longer. The simplest approach is to use Marshal.AllocHGlobal to allocate a bit of memory on the unmanaged heap. You free that memory using Marshal.FreeHGlobal. This is roughly equivalent to using new and delete in C.
I started with your code sample, but had to change a few things to avoid going mad. This doesn't mean that the final sample is 100% correct or a good way of implementing this, I was still only changing a few things in your code to make it work. In a real implementation, I'd make the whole thing a bit differently - if you're interested in some good practices for working with C# and pointers in C# (or in general), you might want to post your full, working code to Code Review - you'll get a lot of good feedback there.
Sample code, including adding and removing items from the list:
void Main()
{
var list = new MyList();
list.InsertAt(0, 'A');
list.InsertAt(1, 'B');
list.InsertAt(2, 'C');
list.InsertAt(1, 'X');
Console.WriteLine(string.Join(", ", list.Select(i => i.ToString())));
list.RemoveAt(1);
Console.WriteLine(string.Join(", ", list.Select(i => i.ToString())));
}
public unsafe struct list
{
public char x;
public list* next;
}
public unsafe class MyList : IEnumerable<char>
{
list* first;
list* last;
int count;
public int Count { get { return count; } }
public bool IsEmpty() { return count == 0; }
private void Remove(list* previous, list* current)
{
if (first == current) first = current->next;
if (last == current) last = previous;
if (previous != null) previous->next = current->next;
Console.WriteLine
(
"Removing {0}, first {1}, last {2}, count {3}",
current->x,
first == null ? '-' : first->x,
last == null ? '-' : last->x,
count
);
count--;
Marshal.FreeHGlobal(new IntPtr(current));
}
public void RemoveAt(int index)
{
if (count < index || index < 0)
throw new ArgumentOutOfRangeException("Index is out of range!");
var current = first;
if (index == 0)
{
Remove(null, current);
return;
}
for (var i = 0; i < index - 1; i++)
{
current = current->next;
}
Remove(current, current->next);
}
~MyList()
{
do
{
RemoveAt(0);
}
while (!IsEmpty());
}
private list* InsertAfter(list* previousItem, char character)
{
var newItem = (list*)Marshal.AllocHGlobal(sizeof(list));
newItem->next = previousItem == null ? null : previousItem->next;
newItem->x = character;
if (previousItem == last) last = newItem;
if (previousItem != null) previousItem->next = newItem;
count++;
Console.WriteLine
(
"Added {0} after {1}, first {2}, last {3}, count {4}",
character,
previousItem == null ? '-' : previousItem->x,
first == null ? '-' : first->x,
last == null ? '-' : last->x,
count
);
return newItem;
}
public void InsertAt(int index, char character)
{
if (count < index || index < 0)
throw new ArgumentOutOfRangeException("Index is out of range!");
if (index == 0)
{
var newItem = InsertAfter(null, character);
if (first != null) newItem->next = first;
first = newItem;
}
else if (index == 1)
{
InsertAfter(first, character);
}
else if (index == count)
{
InsertAfter(last, character);
}
else
{
var current = first;
for (var i = 0; i < index - 2; i++)
{
current = current->next;
}
InsertAfter(current, character);
}
}
private class MyListEnumerator : IEnumerator<char>
{
private MyList list;
private list* current;
public MyListEnumerator(MyList list)
{
this.list = list;
this.current = null;
}
public void Reset() { current = null; }
public bool MoveNext()
{
if (current == null) current = list.first;
else current = current->next;
return current != null;
}
public char Current
{
get
{
if (current == null) throw new InvalidOperationException();
return current->x;
}
}
object IEnumerator.Current { get { return (object)Current; } }
public void Dispose() {}
}
public IEnumerator<char> GetEnumerator() { return new MyListEnumerator(this); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}
I want to implement my own Priority Queue in C# using the naive approach. I need to use PQ for edges in a graph to implement Prims algorithm. Here is what I've done so far:
public class Edge
{
private int v; // one vertex
private int w; // the other vertex
private int weight; // edge weight
public Edge(int v0, int w0, int weight0)
{
v = v0;
w = w0;
weight = weight0;
}
public Edge()
{
v = 0;
w = 0;
weight = 0;
}
public int get_weight()
{
return weight;
}
public int either()
{
return v;
}
public int the_other(int vertex)
{
if (vertex == v) return w;
else return v;
}
public int compareTo(Edge that)
{
if (this.get_weight() < that.get_weight()) return -1;
if (this.get_weight() < that.get_weight()) return 1;
else return 0;
}
public string to_str()
{
string s = v.ToString() + " " + weight.ToString() + " " + w.ToString() + '\n';
return s;
}
}
public class MyPriorityQueue_Edge
{
private List<Edge> q = new List<Edge>();
int size;
public MyPriorityQueue_Edge()
{
size = 0;
}
public void insert(Edge e)
{
q.Add(e);
size++;
}
Edge Min()
{
int min_weight = 1000;
Edge min_edge = new Edge();
foreach(Edge e in q)
if(e.get_weight()< min_weight)
min_edge = e;
return min_edge;
}
public Edge delmin()
{
Edge e = q.Min();
q.Remove(e);
size--;
return e;
}
public bool is_empty()
{
if (size == 0) return true;
else return false;
}
}
When I compile it the compiler points to this line:
Edge e = q.Min();
And says that I did not work on the exception "System.Argument.Exception". How can I fix this?
From MSDN Enumerable.Min<TSource> Method (IEnumerable<TSource>)
If type TSource implements IComparable<T>, this method uses that implementation to compare values. Otherwise, if type TSource implements IComparable, that implementation is used to compare values.
You need to implement IComparable interface in your Edge class.
public class Edge : IComparable
Then add a CompareTo() method. Something like
public int CompareTo(object obj)
{
if (obj is Edge)
{
Edge other = (Edge)obj;
return this.compareTo(other); // you already implemented this in your Edge class
}
else
{
throw new InvalidOperationException();
}
}
Suppose I have a list of multi-part questions and each question has a QuestionNumber like 1, 1a,1b,2,2a and so on. I want to fetch a list of questions from the database using linq-to-entities, but ordered by QuestionNumber. The problem is that rather than using the correct order, it will use lexicographic ordering like
1
11
11a
11b
1a
1b
2
22
What I have so far is a custom comparer:
public class QuestionCompare : IComparer<Question>
{
public int Compare(Question x, Question y)
{
string a = x.QuestionNumber;
string b = y.QuestionNumber;
if (a == b)
{
return 0;
}
int aInt;
bool aBool = Int32.TryParse(new String(a.Where(Char.IsDigit).ToArray()), out aInt);
int bInt;
bool bBool = Int32.TryParse(new String(b.Where(Char.IsDigit).ToArray()), out bInt);
if (aBool)
{
if (bBool)
{
if (aInt > bInt)
{
return 1;
}
else if (aInt < bInt)
{
return -1;
}
else
{
string aLetter = new String(a.Where(Char.IsLetter).ToArray());
string bLetter = new String(a.Where(Char.IsLetter).ToArray());
return StringComparer.CurrentCulture.Compare(aLetter, bLetter);
}
}
else
{
return 1;
}
}
else
{
if (bBool)
{
return -1;
}
else
{
return StringComparer.CurrentCulture.Compare(a, b);
}
}
return 0;
}
}
And you can call Array.Sort(questionArray,new QuestionCompare()) to put the questions in the correct order.
However, I feel like this is a common and well defined order so I'm wondering if there are better implementations, perhaps even something built in to the .Net framework.
This comparer works fine and is a fair bit shorter.
public class QuestionCompare : IComparer<Question>
{
public int Compare(Question x, Question y)
{
string a = x.QuestionNumber;
string b = y.QuestionNumber;
var aDigits = new string(a.TakeWhile(c => char.IsDigit(c)).ToArray());
var bDigits = new string(b.TakeWhile(c => char.IsDigit(c)).ToArray());
int aInt = String.IsNullOrEmpty(aDigits) ? 0 : int.Parse(aDigits);
int bInt = String.IsNullOrEmpty(bDigits) ? 0 : int.Parse(bDigits);
return aInt != bInt ? aInt.CompareTo(bInt) : a.CompareTo(b);
}
}
I want to implement simple Linked list and adding items and its seems that my Add function get into endless loop and i don't know why
public class IntNode
{
private int _value;
private IntNode _next;
public IntNode(int val, IntNode n)
{
_value = val;
_next = n;
}
public int getValue()
{
return _value;
}
public IntNode getNext()
{
return _next;
}
public void setValue(int v)
{
_value = v;
}
public void setNext(IntNode next)
{
_next = next;
}
public string ToString()
{
return _value.ToString();
}
}
public class IntList
{
private IntNode _head;
public static int count;
public IntList()
{
_head = null;
count = 0;
}
public IntList(IntNode node)
{
_head = node;
}
public void Add(IntNode node)
{
if (_head == null)
_head = node;
else
{
for (IntNode p = _head; p.getNext() != null; p.getNext()) { }
_head.setNext(node);
count++;
}
}
public void ToString()
{
IntNode cur = _head;
while (cur.getNext() != null)
{
Console.WriteLine(cur.ToString());
cur = cur.getNext();
}
}
}
main
static void Main(string[] args)
{
IntList list = new IntList();
list.Add(new IntNode(5, null));
list.Add(new IntNode(2, null));
list.Add(new IntNode(8, null));
list.Add(new IntNode(1, null));
list.ToString();
}
The problem is the increment step in the for loop. It needs to be p = p.getNext() not simply p.getNext(). The latter just calls the getNext function and does nothing with the return which means p is never modified and hence the loop doesn't make any progress
for (IntNode p = _head; p.getNext() != null; p = p.getNext()) { }
The next problem is you are not actually moving _head or using the p value. Hence you haven't actually found the place to insert. What you need is something like the following
IntNode p = _head;
while (p.getNext() != null) {
p = p.getNext();
}
p.setNext(node);
for (IntNode p = _head; p.getNext() != null; p.getNext()) { }
You're not using p anywhere, and not doing anything in the loop body. Can you spot your problem?
First, you don't assign the result of getNext() anywhere:
for (IntNode p = _head; p.getNext() != null; p.getNext()) { }
Second, you even don't use the last node anywhere. In fact, you even couldn't, because p doesn't exist outside of the for loop…
Advice: Keep a reference to the last node as well and make your life simpler.
Your loop never ends because p is not incremented.
It should be easier for you if you keep a reference to the last inserted item. For example :
private IntNode _lastNode;
public void Add(IntNode node)
{
if (_head == null)
_head = node;
else
{
if (_lastNode == null)
_lastNode = _head;
_lastNode.setNext(node)
_lastNode = node;
}
count++;
}
You won't have to loop through nodes each time you try to add a node.
I made a Tree Data Structure and I want the Elements to sort like this:
10
/ \
5 12
/ \ / \
3 7 11 18
If the value of the added element is smaller than the value of the other element, it should be linked left, and if bigger, right. My problem is, that I just can't get the sorting method right.
class Tree
{
private class TElement
{
public int _value;
public TElement _left;
public TElement _right;
public TElement(int value)
{
_value = value;
}
}
private TElement RootElement;
public void Add(int value)
{
TElement newElement = new TElement(value);
TElement current = new TElement(value);
current = RootElement;
if (RootElement == null)
{
RootElement = newElement;
return;
}
SortNewElement(RootElement, RootElement, newElement, RootElement);
}
private void SortNewElement(TElement left, TElement right, TElement newElement, TElement RootElement)
{
if (newElement._value < RootElement._value && RootElement._left == null)
{
left._left = newElement;
return;
}
if (newElement._value > RootElement._value && RootElement._right == null)
{
right._right = newElement;
return;
}
if (newElement._value < left._value && left._left == null)
{
left._left = newElement;
return;
}
if (newElement._value > right._value && right._right == null)
{
right._right = newElement;
return;
}
SortNewElement(left._left, right._right, newElement, RootElement);
}
}
I know it doesn't work because it's trying to get the linked nodes of a null element.
From what i can understand from your question you are just trying to insert a new node in a binary search tree. Its inorder traversal will be a sorted array.
You can do so by the following simple pseudo code
insert_new( Node* node, value)
{
if(value > node->value)
{
if(node->right != null)
{
insert_new(node->right,value);
}
else
{
node->right = new Node(value);
return;
}
}
else
{
if(node->left != null)
{
insert_new(node->left,value)
}
else
{
node->left = new Node(value);
return;
}
}
}
class element{
public:
int value;
*element left;
*element right;
element(int value)
value = value;
public add(&element a)
if (a != null)
{
if (left!=null){
left = a;
}
else{
if (left.value > a.value){
right = left;
left= a;
}
else{
right=a;
}
}