Собственно говоря, простейшая задача на создание односвязного списка, с перегрузкой оператора в функциях - добавление в начало списка, удаление из начала списка и сравнение длин списков. Как это же реализовать в шарпе, хотя бы структуру, так как даже не знаю от чего отталкиваться, с шарпом не работал раньше, буду рад любой помощи?
#include "stdafx.h"
#include <iostream>
struct element
{
char a;
element *next;
};
class list
{
public:
list();
void add(char c);
explicit list(char c);
void operator+(char c);
void operator--(int i);
bool operator == (list &l);
void print();
~list();
private:
element *head;
int count;
};
void list::print()
{
if (!head) std::cout << "List is empty\n";
else
{
element *h, *t;
h = head;
do
{
std::cout << h->a << " ";
t = h->next;
h = t;
} while (h);
std::cout << "\n";
}
}
void list::add(char c)
{
if (head == NULL)
{
head = new element;
head->a = c;
head->next = NULL;
count = 1;
}
else
{
element *h;
h = new element;
h->a = c;
h->next = head;
head = h;
count++;
}
}
list::list()
{
head = NULL;
count = 0;
}
list::list(char c)
{
head = new element;
head->a = c;
head->next = NULL;
count = 1;
}
void list::operator+(char c)
{
add(c);
}
void list::operator--(int i)
{
if (!head->next)
{
element *h;
h = head;
head = h->next;
delete h;
count--;
}
else std::cout << "List is empty\n";
}
list::~list()
{
element *h;
if (head)
{
do
{
h = head;
head = h->next;
delete h;
} while (head);
}
}
bool list::operator== (list &l)
{
if ((!head) || (!l.head)) std::cout << "Some List is empty\n";
else
{
if (count == l.count) return true;
}
return false;
}
int main()
{
list ch1('a'), ch2('c');
ch1.print();
ch2.print();
ch1 + 'b';
ch2 + 'd';
ch1.print();
ch2.print();
if (ch1 == ch2) std::cout << "Are equal\n";
else std::cout << "Not equal\n";
}
Это не такая простая задачка. Т.е. ее тупо в лоб решить нельзя. По мне гораздо проще не портировать код, а заново написать. Итак, какие проблемы:
Чтоб совсем не делать за вас всю работу (попробуйте сами поковырять C#), сделал только интерфейс. Код уж сами впишите (как в C++ нельзя выносить объявления, объявление и определение метода должно быть в одном месте)
//к сожалению в структурах запрещены циклические ссылки, но ими никто в c# не пользуется
//имена классов и членов с большой буквы (так принято)
class Element
{
//не данные, а свойства (так принято)
//но если не нужно, можно убрать '{ get; set; }'
public char A { get; set; }
public Element Next { get; set; }
};
class List
{
//нельзя как в c++ писать 'public:', вы должны перед каждым методом писать 'public'
//private - по умолчанию, его можно не писать
//конструктор
public List()
{
}
//деструкторов в c# нет: тут автоматическая сборка мусора
//~list();
/// <summary>
/// Коментарии в таком прикольном виде пишем
/// Добавление элемента в список
/// </summary>
/// <param name="c">данные</param>
public void Add(char c)
{
}
//не могу написать оператор, вместо него будет функция
//public explicit List(char c)
public void CreateFromChar(char c)
{
}
//оказывается все операторы должны быть статические, так что добавляем List в первый аргумент
//вроде не ругается, но я бы через функцию сделал
public static List operator +(List l, char c)
{
return null;
}
public static List operator --(List l)
{
return null;
}
public static bool operator ==(List l1, List l2)
{
return false;
}
//оператор '==' должен быть вместе с '!='
public static bool operator !=(List l1, List l2)
{
return true;
}
//эти два метода тоже придется реализовать, иначе на '==' ругается
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public void Print()
{
}
//приватные члены, можем ключевое слово 'private' опустить
//опять же оформил как свойства, но можем и как обычные данные сделать
Element Head { get; set; }
int Count { get; set; }
}
Update: как реализовать методы Equals и GetHashCode
Это два разных метода для поддержки операций сравнения в C#, у них нет аналогов в C++.
Самый простой - это Equals. Он принимает на вход другой объект того же типа и возвращает true, если объект равен this и false, если не равен. Логика метода - это уже ваше дело. Можно считать, что этот метод тоже самое что и оператор '==' в C++ (обычно реализуют 'Equals', а '==' не реализуют, иначе непонятно какой из них используется в сравнении):
class List
{
public override bool Equals(object obj)
{
return true; //напишите здесь правильное сравнение (можно вызвать '==')
}
}
List l1 = new List();
List l2 = new List();
Console.WriteLine(l1.Equals(l2)); //true
//можно было бы написать 'l1 == l2',
//но из-за присутствия оператора '==' в классе, метод Equals не вызовется
GetHashCode() - не имеет аналога в C++. В C# он нужен для правильной работы словарей, они же - ассоциативные массивы. Словарь хранит объекты в соответсвии с их ключами, а ключами в C# являются целые числа. В JavaScript, например, ключами являются строки. В вашем случае можно реализовать GetHashCode() как объединение GetHashCode() для каждого элемента List:
public override int GetHashCode()
{
var e = this.Head;
int res = 0;
int mul = 1;
while (e != null)
{
res += e.A.GetHashCode() * mul;
e = e.Next;
mul *= 17; //волшебное число
}
return res;
}
var l1 = new List();
l1.Add('a');
l1.Add('b');
var l2 = new List();
l2.Add('b');
l2.Add('a');
var d = new Dictionary<List, bool>();
d.Add(l1, true);
Console.WriteLine(d.ContainsKey(l1)); //true
Console.WriteLine(d.ContainsKey(l2)); //false
Виртуальный выделенный сервер (VDS) становится отличным выбором
Нужно реализовать ряд методов, взаимодействующих с веб-страницей на JS для выполнения в Awesomium, такие как найти элемент на странице по XPath, кликнуть...
Как сделать, чтобы при запуске таймера он сразу выполнил код в прикрепленном методе, а не дожидаться отсчета интервала
Помогите разобратьсяСгенерировал crud контроллер