tatca

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 21

 PHẦ N A:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

typedef int Itemtype;


struct BSTNode
{
Itemtype Info;
BSTNode* Left;
BSTNode* Right;
};

struct BSTree
{
BSTNode* Root;
};

BSTNode* createBSTNode(Itemtype x)
{
BSTNode* p = new BSTNode;
if (!p)
{
printf("Khong du bo nho de cap phat!!!");
return NULL;
}
p->Info = x;
p->Left = NULL;
p->Right = NULL;
return p;
}

void initBSTree(BSTree &bst)


{
bst.Root = NULL;
}

int insertBSTNode(BSTNode*& root, BSTNode* p)


{
if (!p)
{
return 0;
}
if (!root)
{
root = p;
return 1;
}
if (root->Info == p->Info)
{
return 0;
}
if (p->Info < root->Info)
insertBSTNode(root->Left, p);
else
insertBSTNode(root->Right, p);
return 1;
}
void createBSTree(BSTree& bst, Itemtype n)
{
Itemtype x;
for (int i = 0; i < n; i++)
{
printf("Nhap Node thu %d: ", i + 1);
scanf_s("%d", &x);
BSTNode* p = createBSTNode(x);
insertBSTNode(bst.Root, p);
}
}

void traverseLNR(BSTNode* root)


{
if (!root)
{
return;
}
traverseLNR(root->Left);
printf("%4d", root->Info);
traverseLNR(root->Right);
}

//Cau 1: Tinh tong cac nut la tren cay:


int tinhtong(BSTNode *root)
{
if (!root)
return 0;
int suml = tinhtong(root->Left);
int sumr = tinhtong(root->Right);
if (!root->Left && !root->Right)
{
return root->Info + suml + sumr;
}
return (suml + sumr);
}

//Cau 2: Xuat cac phan tu tren cay co gia tri lon hon x:
int xuat_phantu_lonhon_x(BSTNode* root,int x)
{
if (!root)
{
return 0;
}
int nlx = xuat_phantu_lonhon_x(root->Left, x);
int nrx = xuat_phantu_lonhon_x(root->Right, x);
if (root->Info > x)
{
printf("%d ", root->Info);
}
return 1;
}

//Cau 3: Dem cac phan tu co chu so 0 o cuoi trong cay:


int dem_phantu(BSTNode* root)
{
if (!root)
{
return 0;
}
int nlx = dem_phantu(root->Left);
int nrx = dem_phantu(root->Right);
if ((root->Info % 100) %10 == 0)
{
return (1 + nlx + nrx);
}
return (nlx + nrx);
}
int main()
{
Itemtype n,x;
BSTree bst;
BSTNode* root = NULL;
initBSTree(bst);
printf("Nhap so luong Node tren cay: ");
scanf_s("%d", &n);
createBSTree(bst, n);
printf("Cay nhi phan tim kiem da tao:\n");
traverseLNR(bst.Root);
printf("\n");
printf("1. Tong cac nut la tren cay: %d\n", tinhtong(bst.Root));
printf("Hay nhap vao x: ");
scanf_s("%d", &x);
printf("2. Phan tu lon hon x la: ");
xuat_phantu_lonhon_x(bst.Root, x);
printf("\n3. So phan tu co chu so 0 o cuoi: %d\n", dem_phantu(bst.Root));
_getch();
return 0;

BÀI THAM KHẢO 2


#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

// Tao struct cho cay


struct TNode {
int data;
TNode* left;
TNode* right;
};

struct tree{
TNode* root;
};

// Khoi tao cay


void initTree(tree& t)
{
t.root = NULL;
}

// Tao tung node trong cay


TNode* createTNode(int x)
{
TNode* p = new TNode;
if (p == NULL)
{
printf("\nKhong du bo nho\n");
return NULL;
}
p->data = x;
p->left = NULL;
p->right = NULL;
return p;
}

// Xuat ra tung phan tu trong cay


void showTNode(TNode* p)
{
printf("%5d", p->data);
}

// In ra tung gia tri cua cay


void showTree(TNode* root)
{
if (!root)
return;
showTNode(root);
showTree(root->left);
showTree(root->right);
}

// Kiem tra cay rong hay ko


bool isEmptyTree(tree t)
{
return (!t.root);
}

// Then phan tu
void insertTNode(TNode*& root, TNode* p)
{
if (!p){
printf("\nKhong thuc hien duoc");
return;
}
if (!root)
{
root = p;
return;
}
if (root->data < p-> data)
insertTNode(root->right, p);
else if (root->data > p->data)
insertTNode(root->left, p);
else
printf("\nGia tri da ton tai trong cay");
}

// Tao cay bang Random


void createTreeByRandom(tree& t)
{
initTree(t);
int n;
printf("\nNhap so luong phan tu trong cay: ");
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
int x;
x = rand() % 20;
TNode* p = createTNode(x);
insertTNode(t.root, p);
}
}

// Cau 1 --------------------------

// --------------------- Bai 1
// Kiem tra nut la
bool isLeaf(TNode* bt)
{
if (!bt)
return false;
if (bt->left == NULL && bt->right == NULL)
return true;
return false;
}

int tongLa(TNode* root)


{
if (root == NULL)
return 0;
if (isLeaf(root))
return root->data + tongLa(root->left) + tongLa(root->right);
return tongLa(root->left) + tongLa(root->right);
}

// --------------------- Bai 2

int max(int x, int y)


{
return x > y ? x : y;
}

int giatriLonNhat(TNode* root)


{
if (root->right == NULL)
return root->data;
return max(root->data, giatriLonNhat(root->right));
}

// --------------------- Bai 3
void demGiaTriChan(TNode* root, int& dem)
{
if (!root)
return;
if (root->data % 2 == 0)
dem++;
demGiaTriChan(root->left, dem);
demGiaTriChan(root->right, dem);
}
// Cau 2 --------------------------

// --------------------- Bai 1
// Tao truct danh sach chua thong tin sinh vien
struct SinhVien {
char mssv[10];
float diem;
};

struct node {
SinhVien data;
node* next;
};

struct list {
node *head, *tail;
};

// Khoi tao danh sach


void initList(list &l) {
l.head = l.tail = NULL;
}

bool isEmpty(list l){


return (!l.head);
}

// Tao nut voi kieu du lieu sinh vien


node* createNode(SinhVien x)
{
node* p = new node;
if (p == NULL)
{
printf("Khong the cap phat bo nho");
_getch();
return NULL;
}p->data = x;
p->next = NULL;
return p;
}

// Nhap thong tin sinh vien


void input(SinhVien &x){
printf("\nNhap ma so sinh vien: ");
gets(x.mssv);
printf("Nhap diem mon tin: ");
scanf("%f%*c", &x.diem);
}

// Them nut vao cuoi danh sach


void insertTail(list& l, node* p)
{
if (!p){
printf("\nKhong thuc hien duoc");
return;
}
if (isEmpty(l))
l.head = l.tail = p;
else
{
l.tail->next = p;
l.tail = p;
}
}

// ----------------------- bai 4
// Tao danh sach sinh vien bang cach nhap
void createList(list& l)
{
int n;
SinhVien x;
printf("Nhap so luong sinh vien gioi tin hoc: ");
scanf("%d%*c", &n);
for (int i = 1; i <= n; i++)
{
input(x);
node* p = createNode(x);
insertTail(l, p);
}
}

//------------------------- bai 5
// Tao dang bang
void bang(){
printf("\t%-4s %-10s %s\n", "STT", "Ma so", "Diem");
}

// In ra toan bo thong tin sinh vien dang bang


void showList(list sl){
if (isEmpty(sl) == 1)
{
printf("\nDanh sach rong!");
return;
}
node* p = sl.head;
int n = 1;
bang();
while (p != NULL)
{
printf("\n\t%-4d %-10s %.2f", n++, p->data.mssv, p->data.diem);
p = p->next;
}
}

//--------------------- bai 6
node* findNode(list l, char* x)
{
for (node* p = l.head; p != NULL; p = p->next)
{
if (strcmp(p->data.mssv, x) == 0)
return p;
}
return NULL;
}
// ------------------------- bai 7

void deleteTail(list& l) {
if (isEmpty(l))
return;
if (l.head->next == NULL) {
l.head = l.tail = NULL;
}
else {
node* p = l.tail;
node* q = l.head;
while (q->next != p)
{
q = q->next;
}
l.tail = q;
l.tail->next = NULL;
delete p;
}
}

void deleteX(list &l, char* x){


if (isEmpty(l)){
printf("\nKhong thuc hien duoc");
return;
}
node* p = l.head;
node* q = NULL;
if (strcmpi(l.tail->data.mssv, x) == 0){
deleteTail(l);
return;
}
while (p->next->next != NULL)
{
if (strcmp(p->next->data.mssv, x) == 0)
break;
p = p->next;
q = p ->next;
}
if (strcmp(p->next->data.mssv, x) != 0) {
printf("\nDanh sach khong chua thong tin sinh vien nay!");
return;
}
else {
node* k = q;
q = q->next;
p->next = q;
delete k;
}
}

void menu(){
printf("\n\t+- - - - - - - - - - Menu- - - - - - - - - - - - - - -+");
printf("\n\t|\t Cau 1: |");
printf("\n\t| 1. Tao va hien thi danh sach trong cay |");
printf("\n\t| 2. Tinh tong cac nut la tren cay |");
printf("\n\t| 3. Xuat gia tri lon nhat trong cay |");
printf("\n\t| 4. Dem cac phan tu chan trong cay |");
printf("\n\t|\t Cau 2: |");
printf("\n\t| 5. Nhap danh sach sinh vien |");
printf("\n\t| 6. Tra diem sinh vien |");
printf("\n\t| 7. Xoa mot sinh vien voi ma so duoc cung cap |");
printf("\n\t+- - - - - - - - - - - - - - - - - - - - - - - - - - -+");
}

void Process(){
int choice;
tree t;
list l;
initTree(t);
initList(l);
do
{
menu();
printf("\n\tNhap lua chon: ");
scanf("%d%*c", &choice);
while (choice < 0)
{
printf("\n\tNhap lai lua chon: ");
scanf("%d%*c", &choice);
}
switch (choice)
{
case 1:{
createTreeByRandom(t);
showTree(t.root);
break;
}
case 2:{
if (!t.root)
printf("\n\tKhong thuc hien duoc");
else
printf("\n\tTong cac nut la la: %d", tongLa(t.root));
break;
}
case 3:{
if (!t.root)
printf("\n\tKhong thuc hien duoc");
else
printf("\n\tNut co gia tri lon nhat trong cay: %d",
giatriLonNhat(t.root));
break;
}
case 4:{
int k = 0;
demGiaTriChan(t.root, k);
printf("\n\tSo luong gia tri chan: %d", k);
break;
}
case 5:{
createList(l);
showList(l);
break;
}
case 6:{
char a[10];
printf("\n\tNhap ma so sinh vien can tra diem: ");
gets(a);
node* q = findNode(l, a);
if (!q)
printf("\n\tKhong tim thay sinh vien trong danh sach");
else
printf("\n\n\tMa so: %-10s \n\tDiem: %.2f", q->data.mssv,
q->data.diem);
break;
}
case 7:{
char a[10];
printf("\n\tNhap ma so sinh vien can xoa: ");
gets(a);
deleteX(l, a);
printf("\n\tDanh sach sinh vien sau khi xoa: \n");
showList(l);
break;
}
}
} while (choice != 0);

}
int main(){
Process();
return 0;
_getch();
}

BÀI THAM KHẢO 3


#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

struct Node
{
int Data;
Node* Left;
Node *Right;
};

struct Tree
{
Node *Root;
};

Node *CreateNode(int x)
{
Node *p = new Node;
if (p == NULL)
{
printf("\nKhong du bo nho");
return NULL;
}
p->Data = x;
p->Left = NULL;
p->Right = NULL;
return p;
}

void EmptyTree(Tree &sl)


{
sl.Root = NULL;
}

int CreateTree(Node *&root, Node *p)


{
if (p == NULL)
return 0;

if (root == NULL)
{
root = p;
return 1;
}

else
{
if (p->Data < root->Data)
CreateTree(root->Left, p);
else
CreateTree(root->Right, p);
}
return 1;
}

void DocMang(int a[], Tree &ROOT, int n)


{
printf("\nMang nay co 7 ptu");
for (int i = 0; i < n; i++)
{
CreateTree(ROOT.Root, CreateNode(a[i]));
}
printf("\nDa xong");
}

int TinhTongLa(Node *root)


{
int tong = 0;
if (root == NULL)
return 0;
if ((root->Left == NULL) && (root->Right == NULL))
{
return tong += root->Data;
}
return TinhTongLa(root->Left) + TinhTongLa(root->Right);
}

int Max(Node *root)


{
int max;
Node *p = root;
while (p != NULL)
{
max = p->Data;
p = p->Right;
}
return max;
}

int DemChan(Node *root)


{
if (root == NULL)
return 0;
if (root->Data % 2 == 0)
return 1;
return DemChan(root->Left) + DemChan(root->Right);
}

int main()
{
int a[9] = {7, 5, 4, 6, 8, 9};
int n = 6;
int tong = 0;
Tree ROOT;
EmptyTree(ROOT);
DocMang(a, ROOT, n);
printf("\n\n");
printf("\nTong cac nut la : %d", TinhTongLa(ROOT.Root));
printf("\nGia tri lon nhat la : %d", Max(ROOT.Root));
printf("\nCo %d ptu chan trong cay", DemChan(ROOT.Root));
getch();
return 1;
}

----------------------------------------------------------------------------------------------------
----------------
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

struct SinhVien
{
int MSSV;
float diem;
};

struct Node
{
SinhVien Data;
Node* Next;
};

struct DS
{
Node *Head;
Node *Tail;
};
Node *CreateNode(SinhVien x)
{
Node *p = new Node;
if (p == NULL)
{
printf("\nKhong du bo nho");
return NULL;
}
p->Data = x;
p->Next = NULL;
return p;
}

void EmptyDL(DS &sl)


{
sl.Head = NULL;
sl.Tail = NULL;
}

int CreateDS(DS &sl, Node *p)


{
if (p == NULL)
return 0;
if (sl.Head == NULL)
{
sl.Head = p;
sl.Tail = p;
}

else
{
sl.Tail->Next = p;
sl.Tail = p;
}
return 1;
}

void XuatDs(DS sl)


{
Node *p = sl.Head;
if (p == NULL)
printf("\Ds rong !!!");
else
{
printf("\nDanh sach sinh vien");
while (p != NULL)
{
printf("\n%d | %.2f", p->Data.MSSV, p->Data.diem);
p = p->Next;
}
}
}

Node *TimSinhVien(DS sl, int x)


{
Node * p = sl.Head;
if (p == NULL)
return NULL;
else
{
while (p != NULL)
{
if (p->Data.MSSV == x)
{
return p;
}
p = p->Next;
}
}
return NULL;
}

int XoaSinhVienX(DS &sl, int h)


{
if (sl.Head == NULL)
return 0;
if (sl.Head->Data.MSSV == h) // Xoa dau
{
Node *p = sl.Head;
sl.Head = p->Next;
delete p;
if (sl.Head == NULL)
sl.Tail = NULL;
return 1;
}

else if (sl.Tail->Data.MSSV == h) //Xoa cuoi


{
Node *p = sl.Tail;
Node *q = sl.Head;
while (q->Next != sl.Tail)
{
q = q->Next;
}
sl.Tail = q;
sl.Tail->Next = NULL;
delete p;
return 1;
}
else // Xoa giua.
{
Node *p = TimSinhVien(sl, h);
Node *q = sl.Head;
while (q->Next != p)
{
q = q->Next;
}
q->Next = p->Next;
delete p;
}
return 1;
}

void MENU()
{
printf("\n1) Nhap sinh vien");
printf("\n2) Xuat danh sach sinh vien");
printf("\n3) Tim kiem mot sinh vien");
printf("\n4) Xoa mot sinh vien");
printf("\n0) Thoat chuong trinh");
}

int main()
{
MENU();
DS sl;
EmptyDL(sl);
int chon;
int nho = 1;

while (nho != 0)
{
printf("\n--------------------------------------------------------");
printf("\nNhap vao lua chon : ");
scanf("%d", &chon);
switch (chon)
{
case 1:
{
SinhVien x;
printf("\nNhap vao ms sinh vien : ");
scanf("%d", &x.MSSV);
printf("\nNhap vao diem sinh vien : ");
scanf("%f", &x.diem);
CreateDS(sl, CreateNode(x));
}
break;

case 2:
{
XuatDs(sl);
}
break;

case 3:
{
int x;
printf("\nNhap vao ma so sinh vien can tim : ");
scanf("%d", &x);
Node *p = TimSinhVien(sl, x);
if (p == NULL)
printf("\nKhong ton tai sinh vien trong ds");
else
printf("MSSV %d co diem la : %.2f", p-
>Data.MSSV, p->Data.diem);
}
break;

case 4:
{
int h;
printf("\nNhap vao ma so sinh vien can xoa : ");
scanf("%d", &h);
if (XoaSinhVienX(sl, h) == 1)
printf("\nDa xoa thanh cong");
else
printf("\nXoa khong thanh cong !!!");
printf("\n");
XuatDs(sl);
}
break;

case 0:
{
nho = 0;
printf("\nThoat chuong trinh");
}
break;

default:
{
printf("\nVui long kiem tra lai");
}
break;
}
}
getch();
return 1;
}
BAI THAM KHAO
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>

struct CongDan
{
char MaDinhDanh[10];
char HoTen[20];
int NamSinh;
};

struct QueueNode
{
CongDan info;
QueueNode *next;
};

struct Queue{
QueueNode *Head;
QueueNode *Tail;
};

QueueNode *CreateQueueNode(CongDan x){


QueueNode *p = new QueueNode;
if (p == NULL){
printf("Khong du bo nho de cap phat!\n");
getch();
return NULL;
}
p->info = x;
p->next = NULL;
return p;
}

int isEmpty(Queue q){


return q.Head == NULL;
}

void initQueue(Queue &q){


q.Head = NULL;
q.Tail = NULL;
}

void showQueueNode(QueueNode *p){


printf("Ma dinh danh Ho ten Nam sinh\n");
printf("%s ", p->info.MaDinhDanh);
printf("%s ", p->info.HoTen);
printf("%d", p->info.NamSinh);
}

void XuatHangDoi(Queue q){


QueueNode *p = q.Head;
printf("\nMa dinh danh Ho ten Nam sinh\n");
while (p != NULL)
{

printf("%s ", p->info.MaDinhDanh);


printf("%s ", p->info.HoTen);
printf("%d\n", p->info.NamSinh);
p = p->next;
}
}

void Them(Queue &q,CongDan &cd){


QueueNode *p = CreateQueueNode(cd);
if (p == NULL)
return;
if (isEmpty(q) == 1){
q.Head = p;
}
else
q.Tail->next = p;

q.Tail = p;
}

void ThemDau(Queue &q, CongDan &cd){


QueueNode *p = CreateQueueNode(cd);
if (p == NULL)
return;
if (isEmpty(q) == 1){
q.Head = p;
}
else
p->next = q.Head;
q.Head = p;
}
void Xoa(Queue &q){
QueueNode *p = q.Head;
if (p == NULL)
return;
q.Head = q.Head->next;
if (q.Head == NULL)
q.Tail = NULL;
showQueueNode(p);
delete p;
}

void ThemCongDan(Queue &q, CongDan &cd){


printf("Nhap ma dinh danh cong dan: ");
gets(cd.MaDinhDanh);
printf("Nhap ho ten cong dan:");
gets(cd.HoTen);
printf("Nhap nam sinh cong dan:");
scanf("%d", &cd.NamSinh);
Them(q, cd);
}

int DemCDconlai(Queue q){


int dem = 0;
QueueNode*p = q.Head;
while (p!=NULL)
{
dem++;
p = p->next;
}
return dem;
}

int TgianDoi(Queue q, char *ten){


int dem = 0;
int found = 0;
QueueNode *p = q.Head;
if (isEmpty(q) == 1)
printf("Hang doi rong!");
while (p!=NULL)
{
if (stricmp(p->info.HoTen,ten)==0){
found = 1;
break;
}
dem++;
p = p->next;
}
if (found == 0)
return 0;
return dem;
}

void ThemLon70(Queue &q,CongDan cd){


printf("Nhap ma dinh danh cong dan: ");
gets(cd.MaDinhDanh);
printf("Nhap ho ten cong dan:");
gets(cd.HoTen);
printf("Nhap nam sinh cong dan:");
scanf("%d", &cd.NamSinh);
if ((2024 - cd.NamSinh) >= 70)
ThemDau(q, cd);
}

int CheckOld(Queue q){


QueueNode *p = q.Head;
if (isEmpty(q) == 1){
printf("Hang doi rong!");
return 0;
}
while (p!=NULL)
{
if ((2024 - p->info.NamSinh) >= 70)
return 1;
p = p->next;
}
return 0;
}

int CheckTen(Queue q){


QueueNode *p = q.Head;
while (p!=NULL)
{
if (stricmp(p->info.HoTen, "Nguyen Hong Nhung") == 0)
return 1;
p = p->next;
}
return 0;
}

void Show(){

printf("***************************************************************************************\n");
printf("* 1/Them 1 cong dan vao hang doi. *\n");
printf("* 2/Xuat mot cong dan ra khoi hang doi. *\n");
printf("* 3/Xuat thong tin nguoi dung dau hang doi *\n");
printf("* 4/Cho biet con bao nhieu cong dan trong hang doi. *\n");
printf("* 5/Nhap ho ten con dan. Cho biet cong dan phai doi bao nhieu nguoi. *\
n");
printf("* 6/Nhap cong dan. neu lon hon hoac bang 70 thi them vao dau. *\
n");
printf("* 7/Kiem tra trong hang doi co nguoi gia hay khong. *\n");
printf("* 8/Kiem tra trong hang doi co nguoi ten Nguyen Hong Nhung ko. *\
n");

printf("***************************************************************************************\n");
}

void main(){
Queue q;
CongDan cd;
initQueue(q);
Show();
CongDan cd1 = { "DH2013", "Nguyen Long Vu", 2000 };
CongDan cd2 = { "DH1023", "Le Duc Dai", 1999 };
CongDan cd3 = { "DH2043", "Truong Van Thai Quy", 1994 };
CongDan cd4 = { "DH4555", "Nguyen Hong Nhung", 1939 };
CongDan cd5 = { "DH1838", "Phung Thanh Do", 1998 };
CongDan cd6 = { "DH2984", "Dang Thi Banh", 1940 };
CongDan cd7 = { "DH4552", "Harry Maguire", 1995 };
CongDan cd8 = { "DH2013", "Nguyen Trong Dung", 2012 };
Them(q, cd1);
Them(q, cd2);
Them(q, cd3);
Them(q, cd4);
Them(q, cd5);
Them(q, cd6);
Them(q, cd7);
Them(q, cd8);

int c;
printf("Chon chuc nang:");
scanf("%d", &c);
getchar();
while (c != 0)
{
switch (c)
{
case 1:{
ThemCongDan(q, cd);
XuatHangDoi(q);
break;
}
case 2:{
printf("Thong tin cong dan duoc cho ra khoi hang doi:\n");
Xoa(q);
printf("\nDanh sach cong dan con lai trong hang doi:\n");
XuatHangDoi(q);
break;
}
case 3:{
printf("Thong tin nguoi dung dau hang doi:\n");
QueueNode *p = q.Head;
showQueueNode(p);
break;
}
case 4:{
printf("So cong dan con lai trong hang doi: %d",
DemCDconlai(q));
break;
}
case 5:
{
char ten[20];
printf("Nhap ten cong dan can tinh:");
gets(ten);
if (TgianDoi(q, ten) == 0)
printf("Khong tim thay ten cong dan!");
else
printf("Cong dan %s con phai doi %d nguoi nua!",ten,
TgianDoi(q, ten));
break;
}
case 6:
ThemLon70(q, cd);
XuatHangDoi(q);
break;
case 7:
if (CheckOld(q) == 0)
printf("Khong co nguoi gia trong hang doi.\n");
else
printf("Co nguoi gia trong hang doi!\n");
break;
case 8:
if (CheckTen(q) == 1)
printf("Co nguoi ten Nguyen Hong Nhung!\n");
else
printf("Khong co ai ten Nguyen Hong Nhung!\n");
default:
break;
}
printf("\nChon chuc nang:");
scanf("%d", &c);
getchar();
}
getch();
}

You might also like